Merge "Update related UI if battery is not present" into rvc-qpr-dev
diff --git a/res/layout/battery_header.xml b/res/layout/battery_header.xml
index dca0972..574d7d4 100644
--- a/res/layout/battery_header.xml
+++ b/res/layout/battery_header.xml
@@ -25,6 +25,7 @@
     style="@style/EntityHeader">
 
     <LinearLayout
+        android:id="@+id/battery_info_layout"
         android:layout_width="170dp"
         android:layout_height="wrap_content"
         android:layout_marginStart="72dp"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2e52996..d141823 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5752,6 +5752,11 @@
     <!-- Title to display the battery percentage. [CHAR LIMIT=24] -->
     <string name="battery_header_title_alternate"><xliff:g id="number" example="88">^1</xliff:g><small> <font size="20"><xliff:g id="unit" example="%">%</xliff:g></font></small></string>
 
+    <!-- Summary for top level battery tile if battery is not present. [CHAR LIMIT=NONE] -->
+    <string name="battery_missing_message">Problem reading your battery meter</string>
+    <!-- Summary to battery page if battery is not present. [CHAR LIMIT=NONE] -->
+    <string name="battery_missing_help_message">Problem reading your battery meter. Tap to <annotation id="url">learn more</annotation></string>
+
     <!-- Title for force stop dialog [CHAR LIMIT=30] -->
     <string name="dialog_stop_title">Stop app?</string>
     <!-- Message body for force stop dialog [CHAR LIMIT=NONE] -->
@@ -7272,6 +7277,8 @@
     <string name="help_uri_sim_combination_warning" translatable="false"></string>
     <!-- url for the NFC and payment settings page -->
     <string name="help_uri_nfc_and_payment_settings" translatable="false"></string>
+    <!-- url for battery page if battery is not present -->
+    <string name="help_url_battery_missing" translatable="false"></string>
 
     <!-- User account title [CHAR LIMIT=30] -->
     <string name="user_account_title">Account for content</string>
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 11a5825..bcb68ff 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -273,6 +273,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 88fd1ce..e428d49 100644
--- a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
@@ -30,6 +31,8 @@
 public class TopLevelBatteryPreferenceController extends BasePreferenceController implements
         LifecycleObserver, OnStart, OnStop {
 
+    @VisibleForTesting
+    boolean mIsBatteryPresent = true;
     private final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
     private Preference mPreference;
     private BatteryInfo mBatteryInfo;
@@ -38,6 +41,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);
@@ -69,6 +75,10 @@
 
     @Override
     public CharSequence getSummary() {
+        // Display help message if battery is not present.
+        if (!mIsBatteryPresent) {
+            return mContext.getText(R.string.battery_missing_message);
+        }
         return getDashboardLabel(mContext, mBatteryInfo);
     }
 
diff --git a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
index bbc8faf..c84127b 100644
--- a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
@@ -18,18 +18,25 @@
 
 import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
 
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
 import android.provider.Settings;
 
+import com.android.settings.testutils.shadow.ShadowUtils;
+
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowUtils.class)
 public class BatteryPercentagePreferenceControllerTest {
 
     private static final String PREF_KEY = "battery_percentage";
@@ -43,6 +50,11 @@
         mController = new BatteryPercentagePreferenceController(mContext, PREF_KEY);
     }
 
+    @After
+    public void tearDown() {
+        ShadowUtils.reset();
+    }
+
     private int getPercentageSetting() {
         return Settings.System.getInt(mContext.getContentResolver(), SHOW_BATTERY_PERCENT, 0);
     }
@@ -60,4 +72,11 @@
         final int isOn = getPercentageSetting();
         assertThat(isOn).isEqualTo(0);
     }
+
+    @Test
+    public void getAvailabilityStatus_batteryNotPresent_shouldReturnConditionallyUnavailable() {
+        ShadowUtils.setIsBatteryPresent(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
index 4d5f1a0..742daf2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
@@ -95,6 +95,19 @@
             BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
             BatteryFixSliceTest.ShadowBatteryTipLoader.class
     })
+    public void onReceive_batteryNotPresent_shouldShowHelpMessage() {
+        mChargingIntent.putExtra(BatteryManager.EXTRA_PRESENT, false);
+
+        mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
+
+        verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT);
+    }
+
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+            BatteryFixSliceTest.ShadowBatteryTipLoader.class
+    })
     public void testOnReceive_powerSaveModeChanged_listenerInvoked() {
         mBatteryBroadcastReceiver.onReceive(mContext,
                 new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 63e8a80..a6cf653 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -44,6 +44,7 @@
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.widget.LayoutPreference;
@@ -61,7 +62,7 @@
 import org.robolectric.shadows.ShadowPowerManager;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowEntityHeaderController.class)
+@Config(shadows = {ShadowEntityHeaderController.class, ShadowUtils.class})
 public class BatteryHeaderPreferenceControllerTest {
 
     private static final String PREF_KEY = "battery_header";
@@ -116,7 +117,7 @@
 
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
-        mController = new BatteryHeaderPreferenceController(mContext, PREF_KEY);
+        mController = spy(new BatteryHeaderPreferenceController(mContext, PREF_KEY));
         mLifecycle.addObserver(mController);
         mController.setActivity(mActivity);
         mController.setFragment(mPreferenceFragment);
@@ -129,6 +130,7 @@
     @After
     public void tearDown() {
         ShadowEntityHeaderController.reset();
+        ShadowUtils.reset();
     }
 
     @Test
@@ -214,4 +216,13 @@
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE_UNSEARCHABLE);
     }
+
+    @Test
+    public void displayPreference_batteryNotPresent_shouldShowHelpMessage() {
+        ShadowUtils.setIsBatteryPresent(false);
+
+        mController.displayPreference(mPreferenceScreen);
+
+        verify(mController).showHelpMessage();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 7839e1a..49f7502 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -45,7 +45,6 @@
 import android.view.View;
 import android.widget.TextView;
 
-import androidx.annotation.VisibleForTesting;
 import androidx.loader.app.LoaderManager;
 import androidx.preference.PreferenceScreen;
 
@@ -56,6 +55,7 @@
 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.widget.LayoutPreference;
 
@@ -72,6 +72,7 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
@@ -224,6 +225,7 @@
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void nonIndexableKeys_MatchPreferenceKeys() {
         final Context context = RuntimeEnvironment.application;
         final List<String> niks =
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
index 3775802..10893c9 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
@@ -24,6 +24,8 @@
 
 import android.content.Context;
 
+import com.android.settings.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -66,4 +68,12 @@
         info.chargeLabel = "5% - charging";
         assertThat(getDashboardLabel(mContext, info)).isEqualTo("5% - charging");
     }
+
+    @Test
+    public void getSummary_batteryNotPresent_shouldShowWarningMessage() {
+        mController.mIsBatteryPresent = false;
+
+        assertThat(mController.getSummary())
+                .isEqualTo(mContext.getString(R.string.battery_missing_message));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index eadd33a..5a32f34 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -46,6 +46,7 @@
     private static boolean sIsSystemAlertWindowEnabled;
     private static boolean sIsVoiceCapable;
     private static ArraySet<String> sResultLinks = new ArraySet<>();
+    private static boolean sIsBatteryPresent;
 
     @Implementation
     protected static int enforceSameOwner(Context context, int userId) {
@@ -67,6 +68,7 @@
         sIsDemoUser = false;
         sIsVoiceCapable = false;
         sResultLinks = new ArraySet<>();
+        sIsBatteryPresent = true;
     }
 
     public static void setIsDemoUser(boolean isDemoUser) {
@@ -155,4 +157,13 @@
     public static void setHandledDomains(ArraySet<String> links) {
         sResultLinks = links;
     }
+
+    @Implementation
+    protected static boolean isBatteryPresent(Context context) {
+        return sIsBatteryPresent;
+    }
+
+    public static void setIsBatteryPresent(boolean isBatteryPresent) {
+        sIsBatteryPresent = isBatteryPresent;
+    }
 }