diff --git a/SystemUIGoogle/Android.bp b/SystemUIGoogle/Android.bp index e5b92c7..fbcb76e 100644 --- a/SystemUIGoogle/Android.bp +++ b/SystemUIGoogle/Android.bp @@ -29,6 +29,7 @@ android_library { "nga-lib", "elmyra-lib", "columbus-lib", + "vendor.google.google_battery-V1-java", ], manifest: "AndroidManifest.xml", diff --git a/SystemUIGoogle/src/com/google/android/systemui/googlebattery/AdaptiveChargingManager.java b/SystemUIGoogle/src/com/google/android/systemui/googlebattery/AdaptiveChargingManager.java index df7aefd..c99c3d4 100644 --- a/SystemUIGoogle/src/com/google/android/systemui/googlebattery/AdaptiveChargingManager.java +++ b/SystemUIGoogle/src/com/google/android/systemui/googlebattery/AdaptiveChargingManager.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2022 The PixelExperience Project + * Copyright (C) 2022 StatixOS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +18,12 @@ package com.google.android.systemui.googlebattery; import android.content.Context; -import android.os.IHwBinder; +import android.os.Binder; +import android.os.IBinder; import android.os.LocaleList; +import android.os.ParcelFormatException; import android.os.RemoteException; +import android.os.ServiceManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.text.format.DateFormat; @@ -28,141 +32,138 @@ import java.util.Locale; import java.util.NoSuchElementException; -import vendor.google.google_battery.V1_1.IGoogleBattery; +import vendor.google.google_battery.ChargingStage; +import vendor.google.google_battery.IGoogleBattery; public class AdaptiveChargingManager { + private static final boolean DEBUG = Log.isLoggable("AdaptiveChargingManager", 3); - Context mContext; + private static final String TAG = "AdaptiveChargingManager"; + + private Context mContext; public AdaptiveChargingManager(Context context) { mContext = context; } - private static IGoogleBattery initHalInterface(IHwBinder.DeathRecipient deathRecipient) { - if (DEBUG) { - Log.d("AdaptiveChargingManager", "initHalInterface"); - } - try { - IGoogleBattery service = IGoogleBattery.getService(); - if (service != null && deathRecipient != null) { - service.linkToDeath(deathRecipient, 0L); - } - return service; - } catch (RemoteException | NoSuchElementException e) { - Log.e("AdaptiveChargingManager", "failed to get Google Battery HAL: ", e); - return null; - } + public interface AdaptiveChargingStatusReceiver { + void onDestroyInterface(); + + void onReceiveStatus(int seconds, String stage); } - public static boolean isStageActive(String str) { - return "Active".equals(str); + private Locale getLocale() { + LocaleList locales = mContext.getResources().getConfiguration().getLocales(); + return (locales == null || locales.isEmpty()) ? Locale.getDefault() : locales.get(0); } - public static boolean isStageEnabled(String str) { - return "Enabled".equals(str); + public String formatTimeToFull(long j) { + return DateFormat.format(DateFormat.getBestDateTimePattern(getLocale(), DateFormat.is24HourFormat(mContext) ? "Hm" : "hma"), j).toString(); } - public static boolean isStageActiveOrEnabled(String str) { - return isStageActive(str) || isStageEnabled(str); + public boolean hasAdaptiveChargingFeature() { + return mContext.getPackageManager().hasSystemFeature("com.google.android.feature.ADAPTIVE_CHARGING"); } - public static boolean isActive(String str, int i) { - return isStageActiveOrEnabled(str) && i > 0; + public boolean isAvailable() { + return hasAdaptiveChargingFeature() && shouldShowNotification(); } - private void destroyHalInterface(IGoogleBattery iGoogleBattery, IHwBinder.DeathRecipient deathRecipient) { - if (DEBUG) { - Log.d("AdaptiveChargingManager", "destroyHalInterface"); - } - if (deathRecipient != null) { - try { - iGoogleBattery.unlinkToDeath(deathRecipient); - } catch (RemoteException e) { - Log.e("AdaptiveChargingManager", "unlinkToDeath failed: ", e); - } - } + public boolean shouldShowNotification() { + return DeviceConfig.getBoolean("adaptive_charging", "adaptive_charging_notification", true); } - boolean hasAdaptiveChargingFeature() { - return mContext.getPackageManager().hasSystemFeature("com.google.android.feature.ADAPTIVE_CHARGING"); + public boolean getEnabled() { + return Settings.Secure.getInt(mContext.getContentResolver(), "adaptive_charging", 1) == 1; } - public boolean isAvailable() { - return hasAdaptiveChargingFeature() && DeviceConfig.getBoolean("adaptive_charging", "adaptive_charging_enabled", true); + public void setEnabled(boolean on) { + Settings.Secure.putInt(mContext.getContentResolver(), "adaptive_charging", on ? 1 : 0); } - public boolean shouldShowNotification() { - return DeviceConfig.getBoolean("adaptive_charging", "adaptive_charging_notification", false); + public static boolean isStageActive(String stage) { + return "Active".equals(stage); } - public boolean isEnabled() { - return Settings.Secure.getInt(mContext.getContentResolver(), "adaptive_charging_enabled", 1) == 1; + public static boolean isStageEnabled(String stage) { + return "Enabled".equals(stage); } - private Locale getLocale() { - LocaleList locales = mContext.getResources().getConfiguration().getLocales(); - return (locales == null || locales.isEmpty()) ? Locale.getDefault() : locales.get(0); + public static boolean isStageActiveOrEnabled(String stage) { + return isStageActive(stage) || isStageEnabled(stage); } - public String formatTimeToFull(long j) { - return DateFormat.format(DateFormat.getBestDateTimePattern(getLocale(), DateFormat.is24HourFormat(mContext) ? "Hm" : "hma"), j).toString(); + public static boolean isActive(String state, int seconds) { + return isStageActiveOrEnabled(state) && seconds > 0; } - public boolean setAdaptiveChargingDeadline(int i) { - IGoogleBattery initHalInterface = initHalInterface(null); - boolean z = false; - if (initHalInterface == null) { + public boolean setAdaptiveChargingDeadline(int secondsFromNow) { + IGoogleBattery googBatteryInterface = initHalInterface(null); + if (googBatteryInterface == null) { return false; } + boolean result = false; try { - if (initHalInterface.setChargingDeadline(i) == 0) { - z = true; - } + googBatteryInterface.setChargingDeadline(secondsFromNow); + result = true; } catch (RemoteException e) { - Log.e("AdaptiveChargingManager", "setChargingDeadline failed: ", e); + Log.e(TAG, "setChargingDeadline() failed"); } - destroyHalInterface(initHalInterface, null); - return z; + destroyHalInterface(googBatteryInterface, null); + return result; } public void queryStatus(final AdaptiveChargingStatusReceiver adaptiveChargingStatusReceiver) { - final IHwBinder.DeathRecipient deathRecipient = new IHwBinder.DeathRecipient() { - public void serviceDied(long j) { - if (AdaptiveChargingManager.DEBUG) { - Log.d("AdaptiveChargingManager", "serviceDied"); - } - adaptiveChargingStatusReceiver.onDestroyInterface(); - } - }; - final IGoogleBattery initHalInterface = initHalInterface(deathRecipient); - if (initHalInterface == null) { - adaptiveChargingStatusReceiver.onDestroyInterface(); - return; - } - try { - initHalInterface.getChargingStageAndDeadline(new IGoogleBattery.getChargingStageAndDeadlineCallback() { + IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() { @Override - public void onValues(byte b, String str, int i) { - if (AdaptiveChargingManager.DEBUG) { - Log.d("AdaptiveChargingManager", "getChargingStageDeadlineCallback result: " + ((int) b) + ", stage: \"" + str + "\", seconds: " + i); + public final void binderDied() { + if (DEBUG) { + Log.d("AdaptiveChargingManager", "serviceDied"); } - if (b == 0) { - adaptiveChargingStatusReceiver.onReceiveStatus(str, i); - } - destroyHalInterface(initHalInterface, deathRecipient); adaptiveChargingStatusReceiver.onDestroyInterface(); } - }); - } catch (RemoteException e) { - Log.e("AdaptiveChargingManager", "Failed to get Adaptive Chaging status: ", e); - destroyHalInterface(initHalInterface, deathRecipient); + }; + IGoogleBattery googBatteryIntf = initHalInterface(deathRecipient); + if (googBatteryIntf == null) { adaptiveChargingStatusReceiver.onDestroyInterface(); + return; + } + try { + ChargingStage stage = googBatteryIntf.getChargingStageAndDeadline(); + adaptiveChargingStatusReceiver.onReceiveStatus(stage.deadlineSecs, stage.stage); + } catch (RemoteException | ParcelFormatException e) { + Log.e("AdaptiveChargingManager", "Failed to get Adaptive Charging status: ", e); } + destroyHalInterface(googBatteryIntf, deathRecipient); + adaptiveChargingStatusReceiver.onDestroyInterface(); } - public interface AdaptiveChargingStatusReceiver { - void onDestroyInterface(); + private static void destroyHalInterface(IGoogleBattery iGoogleBattery, IBinder.DeathRecipient deathRecipient) { + if (DEBUG) { + Log.d("AdaptiveChargingManager", "destroyHalInterface"); + } + if (deathRecipient != null && iGoogleBattery != null) { + iGoogleBattery.asBinder().unlinkToDeath(deathRecipient, 0); + } + } - void onReceiveStatus(String str, int i); + private static IGoogleBattery initHalInterface(IBinder.DeathRecipient deathReceiver) { + if (DEBUG) { + Log.d("AdaptiveChargingManager", "initHalInterface"); + } + try { + IBinder binder = Binder.allowBlocking(ServiceManager.waitForDeclaredService("vendor.google.google_battery.IGoogleBattery/default")); + IGoogleBattery batteryInterface = null; + if (binder != null) { + batteryInterface = IGoogleBattery.Stub.asInterface(binder); + if (batteryInterface != null && deathReceiver != null) { + binder.linkToDeath(deathReceiver, 0); + } + } + return batteryInterface; + } catch (RemoteException | NoSuchElementException | SecurityException e) { + Log.e("AdaptiveChargingManager", "failed to get Google Battery HAL: ", e); + return null; + } } } diff --git a/SystemUIGoogle/src/com/google/android/systemui/power/AdaptiveChargingNotification.java b/SystemUIGoogle/src/com/google/android/systemui/power/AdaptiveChargingNotification.java index ca370b3..badb8fc 100644 --- a/SystemUIGoogle/src/com/google/android/systemui/power/AdaptiveChargingNotification.java +++ b/SystemUIGoogle/src/com/google/android/systemui/power/AdaptiveChargingNotification.java @@ -117,7 +117,7 @@ public void onDestroyInterface() { } @Override - public void onReceiveStatus(final String str, final int i) { + public void onReceiveStatus(final int i, final String str) { mHandler.post(() -> handleOnReceiveStatus(str, i, forceUpdate)); } } diff --git a/SystemUIGoogle/src/com/google/android/systemui/statusbar/KeyguardIndicationControllerGoogle.java b/SystemUIGoogle/src/com/google/android/systemui/statusbar/KeyguardIndicationControllerGoogle.java index 65b3989..ead7823 100644 --- a/SystemUIGoogle/src/com/google/android/systemui/statusbar/KeyguardIndicationControllerGoogle.java +++ b/SystemUIGoogle/src/com/google/android/systemui/statusbar/KeyguardIndicationControllerGoogle.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2022 The PixelExperience Project + * Copyright (C) 2022 StatixOS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +23,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.BatteryManager; import android.os.Looper; import android.os.UserHandle; import android.os.UserManager; -import android.provider.DeviceConfig; import android.text.TextUtils; import android.view.accessibility.AccessibilityManager; @@ -52,10 +53,10 @@ import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.tuner.TunerService; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.wakelock.WakeLock; + import com.google.android.systemui.googlebattery.AdaptiveChargingManager; import java.text.NumberFormat; @@ -65,24 +66,41 @@ @SysUISingleton public class KeyguardIndicationControllerGoogle extends KeyguardIndicationController { - private final IBatteryStats mBatteryInfo; + + private boolean mAdaptiveChargingActive; + private boolean mAdaptiveChargingEnabledInSettings; + @VisibleForTesting + private AdaptiveChargingManager mAdaptiveChargingManager; + @VisibleForTesting + private AdaptiveChargingManager.AdaptiveChargingStatusReceiver mAdaptiveChargingStatusReceiver; + private int mBatteryLevel; private final BroadcastDispatcher mBroadcastDispatcher; private final BroadcastReceiver mBroadcastReceiver; private final Context mContext; private final DeviceConfigProxy mDeviceConfig; - private final TunerService mTunerService; - @VisibleForTesting - protected AdaptiveChargingManager mAdaptiveChargingManager; - @VisibleForTesting - protected AdaptiveChargingManager.AdaptiveChargingStatusReceiver mAdaptiveChargingStatusReceiver; - private boolean mAdaptiveChargingActive; - private boolean mAdaptiveChargingEnabledInSettings; - private int mBatteryLevel; private long mEstimatedChargeCompletion; private boolean mInited; private boolean mIsCharging; private KeyguardUpdateMonitorCallback mUpdateMonitorCallback; + protected class GoogleKeyguardCallback extends KeyguardIndicationController.BaseKeyguardCallback { + protected GoogleKeyguardCallback() { + super(); + } + + @Override + public final void onRefreshBatteryInfo(BatteryStatus batteryStatus) { + super.onRefreshBatteryInfo(batteryStatus); + mIsCharging = batteryStatus.status == BatteryManager.BATTERY_STATUS_CHARGING; + mBatteryLevel = batteryStatus.level; + if (mIsCharging) { + triggerAdaptiveChargingStatusUpdate(); + } else { + mAdaptiveChargingActive = false; + } + } + } + @Inject public KeyguardIndicationControllerGoogle( Context context, @@ -105,7 +123,6 @@ public KeyguardIndicationControllerGoogle( KeyguardBypassController keyguardBypassController, AccessibilityManager accessibilityManager, FaceHelpMessageDeferral faceHelpMessageDeferral, - TunerService tunerService, DeviceConfigProxy deviceConfigProxy, KeyguardLogger keyguardLogger, AlternateBouncerInteractor alternateBouncerInteractor, @@ -116,7 +133,7 @@ public KeyguardIndicationControllerGoogle( accessibilityManager, faceHelpMessageDeferral, keyguardLogger, alternateBouncerInteractor, alarmManager); mBroadcastReceiver = new BroadcastReceiver() { @Override - public void onReceive(Context context2, Intent intent) { + public final void onReceive(Context context, Intent intent) { if ("com.google.android.systemui.adaptivecharging.ADAPTIVE_CHARGING_DEADLINE_SET".equals(intent.getAction())) { triggerAdaptiveChargingStatusUpdate(); } @@ -124,61 +141,29 @@ public void onReceive(Context context2, Intent intent) { }; mAdaptiveChargingStatusReceiver = new AdaptiveChargingManager.AdaptiveChargingStatusReceiver() { @Override - public void onDestroyInterface() { - } + public void onDestroyInterface() {} @Override - public void onReceiveStatus(String str, int i) { - boolean z = mAdaptiveChargingActive; - mAdaptiveChargingActive = AdaptiveChargingManager.isActive(str, i); - long j = mEstimatedChargeCompletion; + public void onReceiveStatus(int seconds, String stage) { + boolean wasActive = mAdaptiveChargingActive; + mAdaptiveChargingActive = AdaptiveChargingManager.isActive(stage, seconds); + long currentEstimation = mEstimatedChargeCompletion; long currentTimeMillis = System.currentTimeMillis(); - TimeUnit timeUnit = TimeUnit.SECONDS; - mEstimatedChargeCompletion = currentTimeMillis + timeUnit.toMillis(i + 29); - long abs = Math.abs(mEstimatedChargeCompletion - j); - if (z != mAdaptiveChargingActive || (mAdaptiveChargingActive && abs > timeUnit.toMillis(30L))) { + mEstimatedChargeCompletion = TimeUnit.SECONDS.toMillis(seconds + 29) + currentTimeMillis; + long abs = Math.abs(mEstimatedChargeCompletion - currentEstimation); + if (mAdaptiveChargingActive != wasActive || (mAdaptiveChargingActive && abs > TimeUnit.SECONDS.toMillis(30L))) { updateDeviceEntryIndication(true); } } }; mContext = context; mBroadcastDispatcher = broadcastDispatcher; - mTunerService = tunerService; mDeviceConfig = deviceConfigProxy; mAdaptiveChargingManager = new AdaptiveChargingManager(context); - mBatteryInfo = iBatteryStats; - } - - @Override - public void init() { - super.init(); - if (mInited) { - return; - } - mInited = true; - mTunerService.addTunable(new TunerService.Tunable() { - @Override - public final void onTuningChanged(String str, String str2) { - refreshAdaptiveChargingEnabled(); - } - }, "adaptive_charging_enabled"); - mDeviceConfig.addOnPropertiesChangedListener("adaptive_charging", mContext.getMainExecutor(), new DeviceConfig.OnPropertiesChangedListener() { // from class: com.google.android.systemui.statusbar.KeyguardIndicationControllerGoogle$$ExternalSyntheticLambda0 - public final void onPropertiesChanged(DeviceConfig.Properties properties) { - if (properties.getKeyset().contains("adaptive_charging_enabled")) { - triggerAdaptiveChargingStatusUpdate(); - } - } - }); - triggerAdaptiveChargingStatusUpdate(); - mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, new IntentFilter("com.google.android.systemui.adaptivecharging.ADAPTIVE_CHARGING_DEADLINE_SET"), null, UserHandle.ALL); - } - - private void refreshAdaptiveChargingEnabled() { - mAdaptiveChargingEnabledInSettings = mAdaptiveChargingManager.isAvailable() && mAdaptiveChargingManager.isEnabled(); } @Override - protected String computePowerIndication() { + public String computePowerIndication() { if (mIsCharging && mAdaptiveChargingEnabledInSettings && mAdaptiveChargingActive) { String formatTimeToFull = mAdaptiveChargingManager.formatTimeToFull(mEstimatedChargeCompletion); return mContext.getResources().getString(R.string.adaptive_charging_time_estimate, NumberFormat.getPercentInstance().format(mBatteryLevel / 100.0f), formatTimeToFull); @@ -202,30 +187,39 @@ public void setReverseChargingMessage(CharSequence charSequence) { } } - private void triggerAdaptiveChargingStatusUpdate() { - refreshAdaptiveChargingEnabled(); - if (mAdaptiveChargingEnabledInSettings) { - mAdaptiveChargingManager.queryStatus(mAdaptiveChargingStatusReceiver); + private void refreshAdaptiveChargingEnabled() { + boolean supported = mAdaptiveChargingManager.isAvailable(); + if (supported) { + mAdaptiveChargingEnabledInSettings = mAdaptiveChargingManager.getEnabled(); } else { - mAdaptiveChargingActive = false; + mAdaptiveChargingEnabledInSettings = false; } } - protected class GoogleKeyguardCallback extends KeyguardIndicationController.BaseKeyguardCallback { - protected GoogleKeyguardCallback() { - super(); + @Override + public final void init() { + super.init(); + if (mInited) { + return; } + mInited = true; + DelayableExecutor delayableExecutor = mExecutor; + mDeviceConfig.addOnPropertiesChangedListener("adaptive_charging", delayableExecutor, + (properties) -> { + if (properties.getKeyset().contains("adaptive_charging_enabled")) { + triggerAdaptiveChargingStatusUpdate(); + } + }); + triggerAdaptiveChargingStatusUpdate(); + mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, new IntentFilter("com.google.android.systemui.adaptivecharging.ADAPTIVE_CHARGING_DEADLINE_SET"), null, UserHandle.ALL); + } - @Override - public void onRefreshBatteryInfo(BatteryStatus batteryStatus) { - mIsCharging = batteryStatus.status == 2; - mBatteryLevel = batteryStatus.level; - super.onRefreshBatteryInfo(batteryStatus); - if (mIsCharging) { - triggerAdaptiveChargingStatusUpdate(); - } else { - mAdaptiveChargingActive = false; - } + public void triggerAdaptiveChargingStatusUpdate() { + refreshAdaptiveChargingEnabled(); + if (mAdaptiveChargingEnabledInSettings) { + mAdaptiveChargingManager.queryStatus(mAdaptiveChargingStatusReceiver); + } else { + mAdaptiveChargingActive = false; } } } diff --git a/SystemUIGoogle/src/com/google/android/systemui/statusbar/phone/CentralSurfacesGoogle.java b/SystemUIGoogle/src/com/google/android/systemui/statusbar/phone/CentralSurfacesGoogle.java index 314c41c..4623afd 100644 --- a/SystemUIGoogle/src/com/google/android/systemui/statusbar/phone/CentralSurfacesGoogle.java +++ b/SystemUIGoogle/src/com/google/android/systemui/statusbar/phone/CentralSurfacesGoogle.java @@ -222,7 +222,6 @@ public CentralSurfacesGoogle( ExtensionController extensionController, UserInfoControllerImpl userInfoControllerImpl, PhoneStatusBarPolicy phoneStatusBarPolicy, - KeyguardIndicationController keyguardIndicationController, DemoModeController demoModeController, Lazy notificationShadeDepthControllerLazy, StatusBarTouchableRegionManager statusBarTouchableRegionManager, @@ -274,7 +273,7 @@ public CentralSurfacesGoogle( pluginManager, shadeController, statusBarKeyguardViewManager, viewMediatorCallback, initController, timeTickHandler, pluginDependencyProvider, keyguardDismissUtil, extensionController, userInfoControllerImpl, phoneStatusBarPolicy, - keyguardIndicationController, demoModeController, + keyguardIndicationControllerGoogle, demoModeController, notificationShadeDepthControllerLazy, statusBarTouchableRegionManager, notificationIconAreaController, brightnessSliderFactory, screenOffAnimationController, wallpaperController, ongoingCallController,