Update related UI if battery is not present
This change is to update the related UI in the battery page if the
battery is not present. This includes the following updates:
1. Update the summary of battery tile in the Settings homepage
2. Replace the battery level with "Unknown"
3. Replace the summary with help message in the battery page
4. Remove the battery meter icon
Bug: 171368508
Test: verify on an issue device
Change-Id: I892e0d137143160a0bce0c11ce9265120ebb8fd4
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index a7e0eec..f9359a2 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -267,6 +267,15 @@
return batteryChangedIntent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
}
+ /**
+ * Return true if battery is present.
+ */
+ public static boolean isBatteryPresent(Context context) {
+ Intent batteryBroadcast = context.registerReceiver(null /* receiver */,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ return isBatteryPresent(batteryBroadcast);
+ }
+
public static String getBatteryPercentage(Intent batteryChangedIntent) {
return formatPercentage(getBatteryLevel(batteryChangedIntent));
}
diff --git a/src/com/android/settings/display/BatteryPercentagePreferenceController.java b/src/com/android/settings/display/BatteryPercentagePreferenceController.java
index e1bbbfc..945ce47 100644
--- a/src/com/android/settings/display/BatteryPercentagePreferenceController.java
+++ b/src/com/android/settings/display/BatteryPercentagePreferenceController.java
@@ -21,9 +21,11 @@
import android.provider.Settings;
import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.internal.R;
+import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
@@ -34,12 +36,27 @@
public class BatteryPercentagePreferenceController extends BasePreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+ private Preference mPreference;
+
public BatteryPercentagePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ if (!Utils.isBatteryPresent(mContext)) {
+ // Disable battery percentage
+ onPreferenceChange(mPreference, false /* newValue */);
+ }
+ }
+
+ @Override
public int getAvailabilityStatus() {
+ if (!Utils.isBatteryPresent(mContext)) {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
return mContext.getResources().getBoolean(
R.bool.config_battery_percentage_setting_available) ? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
diff --git a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
index 99510a2..2041543 100644
--- a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;
+import android.util.Log;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
@@ -41,6 +42,7 @@
*/
public class BatteryBroadcastReceiver extends BroadcastReceiver {
+ private static final String TAG = "BatteryBroadcastRcvr";
/**
* Callback when the following has been changed:
*
@@ -56,12 +58,14 @@
@IntDef({BatteryUpdateType.MANUAL,
BatteryUpdateType.BATTERY_LEVEL,
BatteryUpdateType.BATTERY_SAVER,
- BatteryUpdateType.BATTERY_STATUS})
+ BatteryUpdateType.BATTERY_STATUS,
+ BatteryUpdateType.BATTERY_NOT_PRESENT})
public @interface BatteryUpdateType {
int MANUAL = 0;
int BATTERY_LEVEL = 1;
int BATTERY_SAVER = 2;
int BATTERY_STATUS = 3;
+ int BATTERY_NOT_PRESENT = 4;
}
@VisibleForTesting
@@ -101,9 +105,11 @@
if (intent != null && mBatteryListener != null) {
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
final String batteryLevel = Utils.getBatteryPercentage(intent);
- final String batteryStatus = Utils.getBatteryStatus(
- mContext, intent);
- if (forceUpdate) {
+ final String batteryStatus = Utils.getBatteryStatus(mContext, intent);
+ if (!Utils.isBatteryPresent(intent)) {
+ Log.w(TAG, "Problem reading the battery meter.");
+ mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT);
+ } else if (forceUpdate) {
mBatteryListener.onBatteryChanged(BatteryUpdateType.MANUAL);
} else if(!batteryLevel.equals(mBatteryLevel)) {
mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_LEVEL);
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 468d8c5..7b910a1 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -25,6 +25,10 @@
import android.os.BatteryManager;
import android.os.PowerManager;
import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
@@ -35,7 +39,9 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.utils.AnnotationSpan;
import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.HelpUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -49,6 +55,7 @@
implements PreferenceControllerMixin, LifecycleObserver, OnStart {
@VisibleForTesting
static final String KEY_BATTERY_HEADER = "battery_header";
+ private static final String ANNOTATION_URL = "url";
@VisibleForTesting
BatteryStatusFeatureProvider mBatteryStatusFeatureProvider;
@@ -94,7 +101,11 @@
mBatteryPercentText = mBatteryLayoutPref.findViewById(R.id.battery_percent);
mSummary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
- quickUpdateHeaderPreference();
+ if (com.android.settings.Utils.isBatteryPresent(mContext)) {
+ quickUpdateHeaderPreference();
+ } else {
+ showHelpMessage();
+ }
}
@Override
@@ -146,6 +157,32 @@
mBatteryPercentText.setText(formatBatteryPercentageText(batteryLevel));
}
+ @VisibleForTesting
+ void showHelpMessage() {
+ final LinearLayout batteryInfoLayout =
+ mBatteryLayoutPref.findViewById(R.id.battery_info_layout);
+ // Remove battery meter icon
+ mBatteryMeterView.setVisibility(View.GONE);
+ // Update the width of battery info layout
+ final ViewGroup.LayoutParams params = batteryInfoLayout.getLayoutParams();
+ params.width = LinearLayout.LayoutParams.WRAP_CONTENT;
+ batteryInfoLayout.setLayoutParams(params);
+ mBatteryPercentText.setText(mContext.getText(R.string.unknown));
+ // Add linkable text for learn more
+ final Intent helpIntent = HelpUtils.getHelpIntent(mContext,
+ mContext.getString(R.string.help_url_battery_missing),
+ mContext.getClass().getName());
+ final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan
+ .LinkInfo(mContext, ANNOTATION_URL, helpIntent);
+ if (linkInfo.isActionable()) {
+ mSummary1.setMovementMethod(LinkMovementMethod.getInstance());
+ mSummary1.setText(AnnotationSpan
+ .linkify(mContext.getText(R.string.battery_missing_help_message), linkInfo));
+ } else {
+ mSummary1.setText(mContext.getText(R.string.battery_missing_message));
+ }
+ }
+
private CharSequence formatBatteryPercentageText(int batteryLevel) {
return TextUtils.expandTemplate(mContext.getText(R.string.battery_header_title_alternate),
NumberFormat.getIntegerInstance().format(batteryLevel));
diff --git a/src/com/android/settings/fuelgauge/PowerUsageBase.java b/src/com/android/settings/fuelgauge/PowerUsageBase.java
index 98b62d9..3a5ed6c 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageBase.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageBase.java
@@ -44,6 +44,7 @@
protected BatteryStatsHelper mStatsHelper;
protected UserManager mUm;
private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
+ protected boolean mIsBatteryPresent = true;
@Override
public void onAttach(Activity activity) {
@@ -60,6 +61,9 @@
mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext());
mBatteryBroadcastReceiver.setBatteryChangedListener(type -> {
+ if (type == BatteryBroadcastReceiver.BatteryUpdateType.BATTERY_NOT_PRESENT) {
+ mIsBatteryPresent = false;
+ }
restartBatteryStatsLoader(type);
});
}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 3a5f0ba..57949db 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -56,8 +56,8 @@
import java.util.List;
/**
- * Displays a list of apps and subsystems that consume power, ordered by how much power was
- * consumed since the last time it was unplugged.
+ * Displays a list of apps and subsystems that consume power, ordered by how much power was consumed
+ * since the last time it was unplugged.
*/
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class PowerUsageSummary extends PowerUsageBase implements OnLongClickListener,
@@ -220,7 +220,9 @@
KEY_TIME_SINCE_LAST_FULL_CHARGE);
mBatteryUtils = BatteryUtils.getInstance(getContext());
- restartBatteryInfoLoader();
+ if (Utils.isBatteryPresent(getContext())) {
+ restartBatteryInfoLoader();
+ }
mBatteryTipPreferenceController.restoreInstanceState(icicle);
updateBatteryTipFlag(icicle);
}
@@ -287,6 +289,10 @@
if (context == null) {
return;
}
+ // Skip refreshing UI if battery is not present.
+ if (!mIsBatteryPresent) {
+ return;
+ }
// Skip BatteryTipLoader if device is rotated or only battery level change
if (mNeedUpdateBatteryTip
@@ -295,7 +301,6 @@
} else {
mNeedUpdateBatteryTip = true;
}
-
// reload BatteryInfo and updateUI
restartBatteryInfoLoader();
updateLastFullChargePreference();
@@ -354,6 +359,10 @@
if (getContext() == null) {
return;
}
+ // Skip restartBatteryInfoLoader if battery is not present.
+ if (!mIsBatteryPresent) {
+ return;
+ }
getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
mBatteryInfoLoaderCallbacks);
if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
@@ -378,7 +387,10 @@
@Override
protected void restartBatteryStatsLoader(@BatteryUpdateType int refreshType) {
super.restartBatteryStatsLoader(refreshType);
- mBatteryHeaderPreferenceController.quickUpdateHeaderPreference();
+ // Update battery header if battery is present.
+ if (mIsBatteryPresent) {
+ mBatteryHeaderPreferenceController.quickUpdateHeaderPreference();
+ }
}
@Override
@@ -392,7 +404,6 @@
restartBatteryTipLoader();
}
-
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.power_usage_summary);
}
diff --git a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
index 1936698..c2e6a6f 100644
--- a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.util.FeatureFlagUtils;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -32,6 +33,8 @@
public class TopLevelBatteryPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop {
+ @VisibleForTesting
+ boolean mIsBatteryPresent = true;
private final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
private Preference mPreference;
private BatteryInfo mBatteryInfo;
@@ -40,6 +43,9 @@
super(context, preferenceKey);
mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
mBatteryBroadcastReceiver.setBatteryChangedListener(type -> {
+ if (type == BatteryBroadcastReceiver.BatteryUpdateType.BATTERY_NOT_PRESENT) {
+ mIsBatteryPresent = false;
+ }
BatteryInfo.getBatteryInfo(mContext, info -> {
mBatteryInfo = info;
updateState(mPreference);
@@ -75,7 +81,10 @@
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
-
+ // Display help message if battery is not present.
+ if (!mIsBatteryPresent) {
+ return mContext.getText(R.string.battery_missing_message);
+ }
return getDashboardLabel(mContext, mBatteryInfo);
}