Add a new feature provider for Battery info page

This feature provider contains the APIs to query certain battery info.

Bug: 276399056
Test: robotests
Change-Id: I8f8503f42a6ad1460b4601e44e8b720b91dd13d1
diff --git a/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProvider.java b/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProvider.java
new file mode 100644
index 0000000..1c8fd12
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.batteryinfo;
+
+/**
+ * Feature Provider used for getting battery information.
+ */
+public interface BatteryInfoFeatureProvider {
+
+    /** Returns true if Manufacture date should be shown */
+    boolean isManufactureDateAvailable();
+
+    /** Returns true if First use date should be shown */
+    boolean isFirstUseDateAvailable();
+
+    /** Returns the summary of battery manufacture date */
+    CharSequence getManufactureDateSummary();
+
+    /** Returns the summary of battery first use date */
+    CharSequence getFirstUseDateSummary();
+}
diff --git a/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImpl.java b/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImpl.java
new file mode 100644
index 0000000..36ddad7
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.batteryinfo;
+
+import android.content.Context;
+import android.os.BatteryManager;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+/** Implementation of {@code BatteryInfoFeatureProvider} */
+public class BatteryInfoFeatureProviderImpl implements BatteryInfoFeatureProvider {
+
+    private BatteryManager mBatteryManager;
+    private Context mContext;
+    private long mManufactureDateInSec;
+    private long mFirstUseDateInSec;
+
+    public BatteryInfoFeatureProviderImpl(Context context) {
+        mContext = context;
+        mBatteryManager = mContext.getSystemService(BatteryManager.class);
+    }
+
+    @Override
+    public boolean isManufactureDateAvailable() {
+        return false;
+    }
+
+    @Override
+    public boolean isFirstUseDateAvailable() {
+        return false;
+    }
+
+    @Override
+    public CharSequence getManufactureDateSummary() {
+        if (!isManufactureDateAvailable()) {
+            return null;
+        }
+        final long manufactureDateInSec = getManufactureDate();
+
+        return getFormattedDate(manufactureDateInSec * 1000L);
+    }
+
+    @Override
+    public CharSequence getFirstUseDateSummary() {
+        if (!isFirstUseDateAvailable()) {
+            return null;
+        }
+        final long firstUseDateInSec = getFirstUseDate();
+
+        return getFormattedDate(firstUseDateInSec * 1000L);
+    }
+
+    protected long getManufactureDate() {
+        if (mManufactureDateInSec == 0L) {
+            mManufactureDateInSec = mBatteryManager.getLongProperty(
+                    BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE);
+        }
+        return mManufactureDateInSec;
+    }
+
+    protected long getFirstUseDate() {
+        if (mFirstUseDateInSec == 0L) {
+            mFirstUseDateInSec = mBatteryManager.getLongProperty(
+                    BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE);
+        }
+        return mFirstUseDateInSec;
+    }
+
+    private CharSequence getFormattedDate(long dateInMs) {
+        final Date date = new Date(dateInMs);
+        final CharSequence formattedDate =
+                DateFormat.getDateInstance(DateFormat.LONG).format(date.getTime());
+
+        return formattedDate;
+    }
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 9d81baa..d7c2c34 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -33,6 +33,7 @@
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -204,6 +205,11 @@
      */
     public abstract KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider();
 
+    /**
+     * Retrieves implementation for Battery information feature.
+     */
+    public abstract BatteryInfoFeatureProvider getBatteryInfoFeatureProvider();
+
     public static final class FactoryNotFoundException extends RuntimeException {
         public FactoryNotFoundException(Throwable throwable) {
             super("Unable to create factory. Did you misconfigure Proguard?", throwable);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index d4f1878..10135f2 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -47,6 +47,8 @@
 import com.android.settings.dashboard.DashboardFeatureProviderImpl;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProviderImpl;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
@@ -117,6 +119,7 @@
     private AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
     private WifiFeatureProvider mWifiFeatureProvider;
     private KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider;
+    private BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
 
     @Override
     public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -376,4 +379,12 @@
         }
         return mKeyboardSettingsFeatureProvider;
     }
+
+    @Override
+    public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
+        if (mBatteryInfoFeatureProvider == null) {
+            mBatteryInfoFeatureProvider = new BatteryInfoFeatureProviderImpl(getAppContext());
+        }
+        return mBatteryInfoFeatureProvider;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImplTest.java
new file mode 100644
index 0000000..6c14977
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryInfoFeatureProviderImplTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.batteryinfo;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.BatteryManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class BatteryInfoFeatureProviderImplTest {
+    @Mock
+    private BatteryManager mBatteryManager;
+
+    private Context mContext;
+    private BatteryInfoFeatureProviderImpl mImpl;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(org.robolectric.RuntimeEnvironment.application);
+        doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class);
+        mImpl = spy(new BatteryInfoFeatureProviderImpl(mContext));
+    }
+
+    @Test
+    public void isManufactureDateAvailable_returnFalse() {
+        assertThat(mImpl.isManufactureDateAvailable()).isFalse();
+    }
+
+    @Test
+    public void isFirstUseDateAvailable_returnFalse() {
+        assertThat(mImpl.isFirstUseDateAvailable()).isFalse();
+    }
+
+    @Test
+    public void getManufactureDateSummary_available_returnExpectedDate() {
+        doReturn(true).when(mImpl).isManufactureDateAvailable();
+        when(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE))
+                .thenReturn(1669680000L);
+
+        final CharSequence result = mImpl.getManufactureDateSummary();
+
+        assertThat(result).isEqualTo("November 29, 2022");
+    }
+
+    @Test
+    public void getManufactureDateSummary_unavailable_returnNull() {
+        doReturn(false).when(mImpl).isManufactureDateAvailable();
+
+        assertThat(mImpl.getManufactureDateSummary()).isNull();
+    }
+
+    @Test
+    public void getFirstUseDateSummary_available_returnExpectedDate() {
+        doReturn(true).when(mImpl).isFirstUseDateAvailable();
+        when(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE))
+                .thenReturn(1669680000L);
+
+        final CharSequence result = mImpl.getFirstUseDateSummary();
+
+        assertThat(result).isEqualTo("November 29, 2022");
+    }
+
+    @Test
+    public void getFirstUseDateSummary_unavailable_returnNull() {
+        doReturn(false).when(mImpl).isFirstUseDateAvailable();
+
+        assertThat(mImpl.getFirstUseDateSummary()).isNull();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 4705380..e77229f 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -31,6 +31,7 @@
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -82,6 +83,7 @@
     public final AwareFeatureProvider mAwareFeatureProvider;
     public final FaceFeatureProvider mFaceFeatureProvider;
     public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
+    public final BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
 
     public PanelFeatureProvider panelFeatureProvider;
     public SlicesFeatureProvider slicesFeatureProvider;
@@ -148,6 +150,7 @@
         mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
         mWifiFeatureProvider = mock(WifiFeatureProvider.class);
         mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
+        mBatteryInfoFeatureProvider = mock(BatteryInfoFeatureProvider.class);
     }
 
     @Override
@@ -304,4 +307,9 @@
     public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() {
         return mKeyboardSettingsFeatureProvider;
     }
+
+    @Override
+    public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
+        return mBatteryInfoFeatureProvider;
+    }
 }
diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
index 50589ac..801b52e 100644
--- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
+++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
@@ -27,6 +27,7 @@
 import com.android.settings.bluetooth.BluetoothFeatureProvider
 import com.android.settings.dashboard.DashboardFeatureProvider
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
@@ -187,4 +188,8 @@
     override fun getKeyboardSettingsFeatureProvider(): KeyboardSettingsFeatureProvider {
         TODO("Not yet implemented")
     }
+
+    override fun getBatteryInfoFeatureProvider(): BatteryInfoFeatureProvider {
+        TODO("Not yet implemented")
+    }
 }
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index d749010..ae5f5f5 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -29,6 +29,7 @@
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -77,6 +78,7 @@
     public final AwareFeatureProvider mAwareFeatureProvider;
     public final FaceFeatureProvider mFaceFeatureProvider;
     public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
+    public final BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
 
     public PanelFeatureProvider panelFeatureProvider;
     public SlicesFeatureProvider slicesFeatureProvider;
@@ -134,6 +136,7 @@
         mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
         mWifiFeatureProvider = mock(WifiFeatureProvider.class);
         mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
+        mBatteryInfoFeatureProvider = mock(BatteryInfoFeatureProvider.class);
     }
 
     @Override
@@ -290,4 +293,9 @@
     public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() {
         return mKeyboardSettingsFeatureProvider;
     }
+
+    @Override
+    public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
+        return mBatteryInfoFeatureProvider;
+    }
 }