diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2c3e7f3d12a..185d21ec7b2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2397,6 +2397,7 @@
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 57a96f98806..bd4e0186b3c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -131,7 +131,7 @@
Hearing device settings
- Audio output, shortcut, hearing aid compatibility
+ Shortcut, hearing aid compatibility
For this device
@@ -2648,6 +2648,8 @@
Model
Hardware version
+
+ Manufactured year
Equipment ID
diff --git a/res/xml/hardware_info.xml b/res/xml/hardware_info.xml
index 641f707a65e..e086a486ee0 100644
--- a/res/xml/hardware_info.xml
+++ b/res/xml/hardware_info.xml
@@ -48,4 +48,13 @@
settings:controller="com.android.settings.deviceinfo.hardwareinfo.HardwareRevisionPreferenceController"
settings:enableCopying="true"/>
+
+
+
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
index 1d45c518a6f..c43bde64a35 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
@@ -66,6 +66,7 @@ import android.text.TextUtils.TruncateAt;
import android.util.EventLog;
import android.util.Log;
import android.view.Display;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -155,12 +156,12 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
mHandler = new Handler(getMainLooper());
- mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
- mAppOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
+ mDPM = getSystemService(DevicePolicyManager.class);
+ mAppOps = getSystemService(AppOpsManager.class);
mLayoutInflaternflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
PackageManager packageManager = getPackageManager();
- if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+ if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task");
finish();
return;
@@ -170,7 +171,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
EXTRA_CALLED_FROM_SUPPORT_DIALOG, false);
String action = getIntent().getAction();
- ComponentName who = (ComponentName)getIntent().getParcelableExtra(
+ ComponentName who = (ComponentName) getIntent().getParcelableExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN);
if (who == null) {
String packageName = getIntent().getStringExtra(EXTRA_DEVICE_ADMIN_PACKAGE_NAME);
@@ -226,7 +227,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
int count = avail == null ? 0 : avail.size();
boolean found = false;
- for (int i=0; i
getString(R.string.device_admin_warning_simplified,
- profileOwnerName), profileOwnerName));
+ profileOwnerName), profileOwnerName));
return;
}
setContentView(R.layout.device_admin_add);
- mAdminIcon = (ImageView)findViewById(R.id.admin_icon);
- mAdminName = (TextView)findViewById(R.id.admin_name);
- mAdminDescription = (TextView)findViewById(R.id.admin_description);
+ mAdminIcon = (ImageView) findViewById(R.id.admin_icon);
+ mAdminName = (TextView) findViewById(R.id.admin_name);
+ mAdminDescription = (TextView) findViewById(R.id.admin_description);
mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning);
mProfileOwnerWarning.setText(
mDPM.getResources().getString(SET_PROFILE_OWNER_POSTSETUP_WARNING,
() -> getString(R.string.adding_profile_owner_warning)));
- mAddMsg = (TextView)findViewById(R.id.add_msg);
+ mAddMsg = (TextView) findViewById(R.id.add_msg);
mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander);
final View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
@@ -380,7 +381,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
boolean hideMsgExpander = mAddMsg.getLineCount() <= maxLines;
mAddMsgExpander.setVisibility(hideMsgExpander ? View.GONE : View.VISIBLE);
if (hideMsgExpander) {
- ((View)mAddMsgExpander.getParent()).invalidate();
+ ((View) mAddMsgExpander.getParent()).invalidate();
}
mAddMsg.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
@@ -398,7 +399,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
mCancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER,
- mDeviceAdmin.getActivityInfo().applicationInfo.uid);
+ mDeviceAdmin.getActivityInfo().applicationInfo.uid);
finish();
}
});
@@ -420,58 +421,64 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
final View restrictedAction = findViewById(R.id.restricted_action);
restrictedAction.setFilterTouchesWhenObscured(true);
- restrictedAction.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- if (!mActionButton.isEnabled()) {
- showPolicyTransparencyDialogIfRequired();
- return;
- }
- if (mAdding) {
- addAndFinish();
- } else if (isManagedProfile(mDeviceAdmin)
- && mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) {
- final int userId = UserHandle.myUserId();
- UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- UserManager um = UserManager.get(DeviceAdminAdd.this);
- um.removeUser(userId);
- finish();
- }
- }
- ).show();
- } else if (mUninstalling) {
- mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
- finish();
- } else if (!mWaitingForRemoveMsg) {
- try {
- // Don't allow the admin to put a dialog up in front
- // of us while we interact with the user.
- ActivityManager.getService().stopAppSwitches();
- } catch (RemoteException e) {
- }
- mWaitingForRemoveMsg = true;
- mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
- new RemoteCallback(new RemoteCallback.OnResultListener() {
- @Override
- public void onResult(Bundle result) {
- CharSequence msg = result != null
- ? result.getCharSequence(
- DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
- : null;
- continueRemoveAction(msg);
- }
- }, mHandler));
- // Don't want to wait too long.
- getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
- @Override public void run() {
- continueRemoveAction(null);
- }
- }, 2*1000);
- }
+
+ final View.OnClickListener restrictedActionClickListener = v -> {
+ if (!mActionButton.isEnabled()) {
+ showPolicyTransparencyDialogIfRequired();
+ return;
}
+ if (mAdding) {
+ addAndFinish();
+ } else if (isManagedProfile(mDeviceAdmin)
+ && mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) {
+ final int userId = UserHandle.myUserId();
+ UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserManager um = UserManager.get(DeviceAdminAdd.this);
+ um.removeUser(userId);
+ finish();
+ }
+ }
+ ).show();
+ } else if (mUninstalling) {
+ mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
+ finish();
+ } else if (!mWaitingForRemoveMsg) {
+ try {
+ // Don't allow the admin to put a dialog up in front
+ // of us while we interact with the user.
+ ActivityManager.getService().stopAppSwitches();
+ } catch (RemoteException e) {
+ }
+ mWaitingForRemoveMsg = true;
+ mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
+ new RemoteCallback(new RemoteCallback.OnResultListener() {
+ @Override
+ public void onResult(Bundle result) {
+ CharSequence msg = result != null
+ ? result.getCharSequence(
+ DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
+ : null;
+ continueRemoveAction(msg);
+ }
+ }, mHandler));
+ // Don't want to wait too long.
+ getWindow().getDecorView().getHandler().postDelayed(
+ () -> continueRemoveAction(null), 2 * 1000);
+ }
+ };
+ restrictedAction.setOnKeyListener((view, keyCode, keyEvent) -> {
+ if ((keyEvent.getFlags() & KeyEvent.FLAG_FROM_SYSTEM) == 0) {
+ Log.e(TAG, "Can not activate device-admin with KeyEvent from non-system app.");
+ // Consume event to suppress click.
+ return true;
+ }
+ // Fallback to view click handler.
+ return false;
});
+ restrictedAction.setOnClickListener(restrictedActionClickListener);
}
/**
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index bff998a4a3e..bea0c3389ec 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -120,6 +120,8 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
protected void onCreate(Bundle savedInstanceState) {
mFaceManager = getFaceManager();
+ super.onCreate(savedInstanceState);
+
if (savedInstanceState == null
&& !WizardManagerHelper.isAnySetupWizard(getIntent())
&& !getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false)
@@ -130,8 +132,6 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
finish();
}
- super.onCreate(savedInstanceState);
-
// Wait super::onCreated() then return because SuperNotCalledExceptio will be thrown
// if we don't wait for it.
if (isFinishing()) {
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintAuthenticateSidecar.java b/src/com/android/settings/biometrics/fingerprint/FingerprintAuthenticateSidecar.java
index 426405627ab..f3c8aba4095 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintAuthenticateSidecar.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintAuthenticateSidecar.java
@@ -21,6 +21,7 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.os.CancellationSignal;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.InstrumentedFragment;
/**
@@ -80,7 +81,6 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
- mCancellationSignal = null;
if (mListener != null) {
mListener.onAuthenticationError(errMsgId, errString);
} else {
@@ -108,10 +108,12 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
}
public void stopAuthentication() {
- if (mCancellationSignal != null && !mCancellationSignal.isCanceled()) {
+ if (mCancellationSignal != null) {
+ // This will automatically check if the cancel has been sent and if so
+ // it won't send it again.
mCancellationSignal.cancel();
+ mCancellationSignal = null;
}
- mCancellationSignal = null;
}
public void setListener(Listener listener) {
@@ -129,4 +131,9 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
}
mListener = listener;
}
+
+ @VisibleForTesting
+ boolean isCancelled() {
+ return mCancellationSignal == null || mCancellationSignal.isCanceled();
+ }
}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceController.java b/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceController.java
index 8ad2ecab894..7d10b5b8a7f 100644
--- a/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceController.java
@@ -17,32 +17,51 @@
package com.android.settings.deviceinfo.batteryinfo;
import android.content.Context;
+import android.os.BatteryManager;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
+import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.overlay.FeatureFactory;
+import java.util.concurrent.TimeUnit;
+
/**
* A controller that manages the information about battery first use date.
*/
public class BatteryFirstUseDatePreferenceController extends BasePreferenceController {
- private BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
+ private final BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
+ private final BatteryManager mBatteryManager;
+
+ private long mFirstUseDateInMs;
public BatteryFirstUseDatePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBatterySettingsFeatureProvider = FeatureFactory.getFactory(
- context).getBatterySettingsFeatureProvider(context);
+ context).getBatterySettingsFeatureProvider();
+ mBatteryManager = mContext.getSystemService(BatteryManager.class);
}
@Override
public int getAvailabilityStatus() {
- return mBatterySettingsFeatureProvider.isFirstUseDateAvailable()
+ return mBatterySettingsFeatureProvider.isFirstUseDateAvailable(getFirstUseDate())
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
- return mBatterySettingsFeatureProvider.getFirstUseDateSummary();
+ return isAvailable()
+ ? BatteryUtils.getBatteryInfoFormattedDate(mFirstUseDateInMs)
+ : null;
+ }
+
+ private long getFirstUseDate() {
+ if (mFirstUseDateInMs == 0L) {
+ final long firstUseDateInSec = mBatteryManager.getLongProperty(
+ BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE);
+ mFirstUseDateInMs = TimeUnit.MILLISECONDS.convert(firstUseDateInSec, TimeUnit.SECONDS);
+ }
+ return mFirstUseDateInMs;
}
}
diff --git a/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceController.java b/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceController.java
index 45b299ab5a7..d1b9df03a82 100644
--- a/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceController.java
@@ -17,32 +17,52 @@
package com.android.settings.deviceinfo.batteryinfo;
import android.content.Context;
+import android.os.BatteryManager;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
+import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.overlay.FeatureFactory;
+import java.util.concurrent.TimeUnit;
+
/**
* A controller that manages the information about battery manufacture date.
*/
public class BatteryManufactureDatePreferenceController extends BasePreferenceController {
- private BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
+ private final BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
+ private final BatteryManager mBatteryManager;
+
+ private long mManufactureDateInMs;
public BatteryManufactureDatePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBatterySettingsFeatureProvider = FeatureFactory.getFactory(
- context).getBatterySettingsFeatureProvider(context);
+ context).getBatterySettingsFeatureProvider();
+ mBatteryManager = mContext.getSystemService(BatteryManager.class);
}
@Override
public int getAvailabilityStatus() {
- return mBatterySettingsFeatureProvider.isManufactureDateAvailable()
+ return mBatterySettingsFeatureProvider.isManufactureDateAvailable(getManufactureDate())
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
- return mBatterySettingsFeatureProvider.getManufactureDateSummary();
+ return isAvailable()
+ ? BatteryUtils.getBatteryInfoFormattedDate(mManufactureDateInMs)
+ : null;
+ }
+
+ private long getManufactureDate() {
+ if (mManufactureDateInMs == 0L) {
+ final long manufactureDateInSec = mBatteryManager.getLongProperty(
+ BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE);
+ mManufactureDateInMs = TimeUnit.MILLISECONDS.convert(manufactureDateInSec,
+ TimeUnit.SECONDS);
+ }
+ return mManufactureDateInMs;
}
}
diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt
new file mode 100644
index 00000000000..400ece9a217
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProvider.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.hardwareinfo
+
+/**
+ * Feature provider for hardware info
+ */
+interface HardwareInfoFeatureProvider {
+ /**
+ * Returns the manufactured year
+ */
+ val manufacturedYear: String?
+}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt
new file mode 100644
index 00000000000..54a112bec35
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFeatureProviderImpl.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.hardwareinfo
+
+/**
+ * Feature provider for hardware info
+ */
+object HardwareInfoFeatureProviderImpl : HardwareInfoFeatureProvider {
+ override val manufacturedYear: String?
+ get() = null
+}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt b/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt
new file mode 100644
index 00000000000..0b0eeb750ec
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/hardwareinfo/ManufacturedYearPreferenceController.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.hardwareinfo
+
+import android.content.Context
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.overlay.FeatureFactory
+
+/** Preference controller for Manufactured Year. */
+class ManufacturedYearPreferenceController(context: Context, preferenceKey: String) :
+ BasePreferenceController(context, preferenceKey) {
+ private val year: String? =
+ FeatureFactory.getFactory(context).hardwareInfoFeatureProvider.manufacturedYear
+
+ override fun getAvailabilityStatus(): Int =
+ if (!year.isNullOrEmpty()) AVAILABLE else UNSUPPORTED_ON_DEVICE
+
+ override fun getSummary(): CharSequence = year ?: ""
+}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
index 18fef1a374f..dd13f1c4842 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
@@ -20,15 +20,8 @@ package com.android.settings.fuelgauge;
public interface BatterySettingsFeatureProvider {
/** Returns true if manufacture date should be shown */
- boolean isManufactureDateAvailable();
+ boolean isManufactureDateAvailable(long manufactureDateMs);
/** 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();
-
+ boolean isFirstUseDateAvailable(long firstUseDateMs);
}
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
index ed4795ab785..2dcb1b12004 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
@@ -16,77 +16,16 @@
package com.android.settings.fuelgauge;
-import android.content.Context;
-import android.os.BatteryManager;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
-import java.util.concurrent.TimeUnit;
-
/** Feature provider implementation for battery settings usage. */
public class BatterySettingsFeatureProviderImpl implements BatterySettingsFeatureProvider {
- protected Context mContext;
-
- private BatteryManager mBatteryManager;
- private long mManufactureDateInMs;
- private long mFirstUseDateInMs;
-
- public BatterySettingsFeatureProviderImpl(Context context) {
- mContext = context.getApplicationContext();
- mBatteryManager = mContext.getSystemService(BatteryManager.class);
- }
-
@Override
- public boolean isManufactureDateAvailable() {
+ public boolean isManufactureDateAvailable(long manufactureDateMs) {
return false;
}
@Override
- public boolean isFirstUseDateAvailable() {
+ public boolean isFirstUseDateAvailable(long firstUseDateMs) {
return false;
}
-
- @Override
- public CharSequence getManufactureDateSummary() {
- return isManufactureDateAvailable()
- ? getFormattedDate(getManufactureDate())
- : null;
- }
-
- @Override
- public CharSequence getFirstUseDateSummary() {
- return isFirstUseDateAvailable()
- ? getFormattedDate(getFirstUseDate())
- : null;
- }
-
- protected long getManufactureDate() {
- if (mManufactureDateInMs == 0L) {
- final long manufactureDateInSec = mBatteryManager.getLongProperty(
- BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE);
- mManufactureDateInMs = TimeUnit.MILLISECONDS.convert(manufactureDateInSec,
- TimeUnit.SECONDS);
- }
- return mManufactureDateInMs;
- }
-
- protected long getFirstUseDate() {
- if (mFirstUseDateInMs == 0L) {
- final long firstUseDateInSec = mBatteryManager.getLongProperty(
- BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE);
- mFirstUseDateInMs = TimeUnit.MILLISECONDS.convert(firstUseDateInSec, TimeUnit.SECONDS);
- }
- return mFirstUseDateInMs;
- }
-
- private CharSequence getFormattedDate(long dateInMs) {
- final Instant instant = Instant.ofEpochMilli(dateInMs);
- final String localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate().format(
- DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));
-
- return localDate;
- }
}
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index f5d3950fc2f..29c7591863c 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -64,8 +64,10 @@ import com.google.protobuf.MessageLite;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.time.Duration;
import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
import java.util.List;
/**
@@ -671,6 +673,14 @@ public class BatteryUtils {
}
return summary.toString();
}
+ /** Format the date of battery related info */
+ public static CharSequence getBatteryInfoFormattedDate(long dateInMs) {
+ final Instant instant = Instant.ofEpochMilli(dateInMs);
+ final String localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate().format(
+ DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));
+
+ return localDate;
+ }
/** Builds the battery usage time information for one timestamp. */
private static String buildBatteryUsageTimeInfo(final Context context, long timeInMs,
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 9d81baa9bca..249caa111fb 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.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -110,6 +111,11 @@ public abstract class FeatureFactory {
*/
public abstract SuggestionFeatureProvider getSuggestionFeatureProvider();
+ /**
+ * Retrieves implementation for Hardware Info feature.
+ */
+ public abstract HardwareInfoFeatureProvider getHardwareInfoFeatureProvider();
+
public abstract SupportFeatureProvider getSupportFeatureProvider(Context context);
public abstract MetricsFeatureProvider getMetricsFeatureProvider();
@@ -125,8 +131,7 @@ public abstract class FeatureFactory {
/**
* Gets implementation for Battery Settings provider.
*/
- public abstract BatterySettingsFeatureProvider getBatterySettingsFeatureProvider(
- Context context);
+ public abstract BatterySettingsFeatureProvider getBatterySettingsFeatureProvider();
public abstract DashboardFeatureProvider getDashboardFeatureProvider(Context context);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index d4f18782c05..60adf958545 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.DashboardFeatureProvider;
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.hardwareinfo.HardwareInfoFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
@@ -118,6 +120,11 @@ public class FeatureFactoryImpl extends FeatureFactory {
private WifiFeatureProvider mWifiFeatureProvider;
private KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider;
+ @Override
+ public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() {
+ return HardwareInfoFeatureProviderImpl.INSTANCE;
+ }
+
@Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
return null;
@@ -150,9 +157,9 @@ public class FeatureFactoryImpl extends FeatureFactory {
}
@Override
- public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider(Context context) {
+ public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider() {
if (mBatterySettingsFeatureProvider == null) {
- mBatterySettingsFeatureProvider = new BatterySettingsFeatureProviderImpl(context);
+ mBatterySettingsFeatureProvider = new BatterySettingsFeatureProviderImpl();
}
return mBatterySettingsFeatureProvider;
}
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 216f7db1ac1..943a937a32a 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -71,6 +71,8 @@ public final class ChooseLockSettingsHelper {
// Gatekeeper password handle, which can subsequently be used to generate Gatekeeper
// HardwareAuthToken(s) via LockSettingsService#verifyGatekeeperPasswordHandle
public static final String EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle";
+ public static final String EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW =
+ "request_write_repair_mode_pw";
/**
* When EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL and EXTRA_KEY_UNIFICATION_PROFILE_ID are
@@ -152,6 +154,7 @@ public final class ChooseLockSettingsHelper {
@Nullable private RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
@Nullable private ComponentName mRemoteLockscreenValidationServiceComponent;
private boolean mRequestGatekeeperPasswordHandle;
+ private boolean mRequestWriteRepairModePassword;
private boolean mTaskOverlay;
public Builder(@NonNull Activity activity) {
@@ -335,6 +338,17 @@ public final class ChooseLockSettingsHelper {
return this;
}
+ /**
+ * @param requestWriteRepairModePassword Set {@code true} to request that
+ * LockSettingsService writes the password data to the repair mode file after the user
+ * credential is verified successfully.
+ */
+ @NonNull public Builder setRequestWriteRepairModePassword(
+ boolean requestWriteRepairModePassword) {
+ mRequestWriteRepairModePassword = requestWriteRepairModePassword;
+ return this;
+ }
+
/**
* Support of ActivityResultLauncher.
*
@@ -385,7 +399,7 @@ public final class ChooseLockSettingsHelper {
mBuilder.mRemoteLockscreenValidationSession,
mBuilder.mRemoteLockscreenValidationServiceComponent, mBuilder.mAllowAnyUserId,
mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle,
- mBuilder.mTaskOverlay);
+ mBuilder.mRequestWriteRepairModePassword, mBuilder.mTaskOverlay);
}
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@@ -396,7 +410,7 @@ public final class ChooseLockSettingsHelper {
@Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
@Nullable ComponentName remoteLockscreenValidationServiceComponent,
boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
- boolean taskOverlay) {
+ boolean requestWriteRepairModePassword, boolean taskOverlay) {
Optional> activityClass = determineAppropriateActivityClass(
returnCredentials, forceVerifyPath, userId, remoteLockscreenValidationSession);
if (activityClass.isEmpty()) {
@@ -407,7 +421,7 @@ public final class ChooseLockSettingsHelper {
returnCredentials, external, forceVerifyPath, userId, alternateButton,
checkboxLabel, remoteLockscreenValidation, remoteLockscreenValidationSession,
remoteLockscreenValidationServiceComponent, allowAnyUser, foregroundOnly,
- requestGatekeeperPasswordHandle, taskOverlay);
+ requestGatekeeperPasswordHandle, requestWriteRepairModePassword, taskOverlay);
}
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
@@ -418,7 +432,7 @@ public final class ChooseLockSettingsHelper {
@Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
@Nullable ComponentName remoteLockscreenValidationServiceComponent,
boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
- boolean taskOverlay) {
+ boolean requestWriteRepairModePassword, boolean taskOverlay) {
final Intent intent = new Intent();
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
@@ -442,6 +456,8 @@ public final class ChooseLockSettingsHelper {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, allowAnyUser);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE,
requestGatekeeperPasswordHandle);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW,
+ requestWriteRepairModePassword);
intent.setClassName(SETTINGS_PACKAGE_NAME, activityClass.getName());
intent.putExtra(SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE,
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index fabca6bb983..d409c0f9dfb 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -171,6 +171,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
KeyguardManager.ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL.equals(intent.getAction());
mTaskOverlay = isInternalActivity()
&& intent.getBooleanExtra(KeyguardManager.EXTRA_FORCE_TASK_OVERLAY, false);
+ final boolean prepareRepairMode =
+ KeyguardManager.ACTION_PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL.equals(
+ intent.getAction());
mUserId = UserHandle.myUserId();
if (isInternalActivity()) {
@@ -244,6 +247,17 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
.setExternal(true)
.show();
return;
+ } else if (prepareRepairMode) {
+ final ChooseLockSettingsHelper.Builder builder =
+ new ChooseLockSettingsHelper.Builder(this);
+ launchedCDC = builder.setHeader(mTitle)
+ .setDescription(mDetails)
+ .setExternal(true)
+ .setUserId(mUserId)
+ .setTaskOverlay(mTaskOverlay)
+ .setRequestWriteRepairModePassword(true)
+ .setForceVerifyPath(true)
+ .show();
} else if (isEffectiveUserManagedProfile && isInternalActivity()) {
mCredentialMode = CREDENTIAL_MANAGED;
if (isBiometricAllowed(effectiveUserId, mUserId)) {
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
index f4cfabc754c..5a123b89315 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
@@ -105,6 +105,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
protected final Handler mHandler = new Handler();
protected boolean mFrp;
protected boolean mRemoteValidation;
+ protected boolean mRequestWriteRepairModePassword;
protected CharSequence mAlternateButtonText;
protected BiometricManager mBiometricManager;
@Nullable protected RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
@@ -130,6 +131,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, false);
mForceVerifyPath = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false);
+ mRequestWriteRepairModePassword = intent.getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW, false);
if (intent.getBooleanExtra(IS_REMOTE_LOCKSCREEN_VALIDATION, false)) {
if (FeatureFlagUtils.isEnabled(getContext(),
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index 03b89f25051..1b535069f3c 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -496,7 +496,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
} else if (mForceVerifyPath) {
if (isInternalActivity()) {
- startVerifyPassword(credential, intent, 0 /* flags */);
+ final int flags = mRequestWriteRepairModePassword
+ ? LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW : 0;
+ startVerifyPassword(credential, intent, flags);
return;
}
} else {
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index e99a986ebe6..3951bde9bac 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -512,7 +512,9 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
}
} else if (mForceVerifyPath) {
if (isInternalActivity()) {
- startVerifyPattern(credential, intent, 0 /* flags */);
+ final int flags = mRequestWriteRepairModePassword
+ ? LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW : 0;
+ startVerifyPattern(credential, intent, flags);
return;
}
} else {
diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
index c4da1335509..df15e5c32f8 100644
--- a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
@@ -40,6 +40,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.hardware.face.Face;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
@@ -116,6 +117,7 @@ public class FaceEnrollIntroductionTest {
private FaceEnrollIntroduction mSpyActivity;
private FakeFeatureFactory mFakeFeatureFactory;
private ShadowUserManager mUserManager;
+ private Resources mResources;
enum GateKeeperAction {CALL_SUPER, RETURN_BYTE_ARRAY, THROW_CREDENTIAL_NOT_MATCH}
@@ -245,6 +247,14 @@ public class FaceEnrollIntroductionTest {
when(mFaceManager.getEnrolledFaces(anyInt())).thenReturn(faces);
}
+ private void setFaceManagerToHaveWithUserId(int numEnrollments, int userId) {
+ List faces = new ArrayList<>();
+ for (int i = 0; i < numEnrollments; i++) {
+ faces.add(new Face("Face " + i /* name */, 1 /*faceId */, 1 /* deviceId */));
+ }
+ when(mFaceManager.getEnrolledFaces(userId)).thenReturn(faces);
+ }
+
@Test
public void intro_CheckCanEnroll() {
setFaceManagerToHave(0 /* numEnrollments */);
@@ -546,4 +556,40 @@ public class FaceEnrollIntroductionTest {
assertThat(mActivity.getPostureCallback()).isNull();
}
+ @Test
+ public void testFaceEnrollIntroduction_maxFacesNotEnrolled_addUserProfile() {
+ // Enroll a face for one user
+ setFaceManagerToHaveWithUserId(1, 0);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mResources = spy(mContext.getResources());
+ when(mResources.getInteger(R.integer.suw_max_faces_enrollable)).thenReturn(1);
+
+ mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, new Intent());
+ mActivity = (TestFaceEnrollIntroduction) mController.get();
+
+ mController.create();
+
+ // The maximum number of faces is already enrolled
+ int result = mActivity.checkMaxEnrolled();
+ assertThat(result).isEqualTo(R.string.face_intro_error_max);
+
+ // Add another user profile
+ mUserManager.addUser(10, "", 0);
+ final Intent intent = new Intent();
+ intent.putExtra(Intent.EXTRA_USER_ID, 10);
+
+ when(mResources.getInteger(R.integer.suw_max_faces_enrollable)).thenReturn(2);
+
+ mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
+ mActivity = (TestFaceEnrollIntroduction) mController.get();
+
+ mController.create();
+
+ // The maximum number of faces hasn't been enrolled, so a new face
+ // can be enrolled for the added user profile
+ result = mActivity.checkMaxEnrolled();
+ assertThat(result).isEqualTo(0);
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
index 18b05add7ad..1998d56b1ca 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
@@ -44,6 +44,7 @@ import android.hardware.biometrics.SensorProperties;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -68,6 +69,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -92,6 +94,16 @@ public class FingerprintSettingsFragmentTest {
@Mock
private FragmentTransaction mFragmentTransaction;
+ @Captor
+ private ArgumentCaptor mCancellationSignalArgumentCaptor =
+ ArgumentCaptor.forClass(CancellationSignal.class);
+ @Captor
+ private ArgumentCaptor
+ mAuthenticationCallbackArgumentCaptor = ArgumentCaptor.forClass(
+ FingerprintManager.AuthenticationCallback.class);
+
+ private FingerprintAuthenticateSidecar mFingerprintAuthenticateSidecar;
+
@Before
public void setUp() {
doReturn(true).when(mFingerprintManager).isHardwareDetected();
@@ -146,6 +158,34 @@ public class FingerprintSettingsFragmentTest {
false)).isTrue();
}
+ // Test the case when FingerprintAuthenticateSidecar receives an error callback from the
+ // framework or from another authentication client. The cancellation signal should not be set
+ // to null because there may exist a running authentication client.
+ // The signal can only be cancelled from the caller in FingerprintSettings.
+ @Test
+ public void testCancellationSignalLifeCycle() {
+ setUpFragment(false);
+
+ mFingerprintAuthenticateSidecar.setFingerprintManager(mFingerprintManager);
+
+ doNothing().when(mFingerprintManager).authenticate(any(),
+ mCancellationSignalArgumentCaptor.capture(),
+ mAuthenticationCallbackArgumentCaptor.capture(), any(), anyInt());
+
+ mFingerprintAuthenticateSidecar.startAuthentication(1);
+
+ assertThat(mAuthenticationCallbackArgumentCaptor.getValue()).isNotNull();
+ assertThat(mCancellationSignalArgumentCaptor.getValue()).isNotNull();
+
+ // Authentication error callback should not cancel the signal.
+ mAuthenticationCallbackArgumentCaptor.getValue().onAuthenticationError(0, "");
+ assertThat(mFingerprintAuthenticateSidecar.isCancelled()).isFalse();
+
+ // The signal should be cancelled when caller stops the authentication.
+ mFingerprintAuthenticateSidecar.stopAuthentication();
+ assertThat(mFingerprintAuthenticateSidecar.isCancelled()).isTrue();
+ }
+
private void setUpFragment(boolean showChooseLock) {
Intent intent = new Intent();
if (!showChooseLock) {
@@ -166,6 +206,10 @@ public class FingerprintSettingsFragmentTest {
doReturn(fragmentManager).when(mFragment).getFragmentManager();
doReturn(fragmentManager).when(mActivity).getSupportFragmentManager();
+ mFingerprintAuthenticateSidecar = new FingerprintAuthenticateSidecar();
+ doReturn(mFingerprintAuthenticateSidecar).when(fragmentManager).findFragmentByTag(
+ "authenticate_sidecar");
+
doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt());
setSensor();
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceControllerTest.java
index a7f6a2e4a2b..9ac69af4462 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryFirstUseDatePreferenceControllerTest.java
@@ -21,9 +21,12 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
+import android.os.BatteryManager;
import androidx.test.core.app.ApplicationProvider;
@@ -33,16 +36,23 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowBatteryManager;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBatteryManager.class})
public class BatteryFirstUseDatePreferenceControllerTest {
private BatteryFirstUseDatePreferenceController mController;
private Context mContext;
+ private BatteryManager mBatteryManager;
+ private ShadowBatteryManager mShadowBatteryManager;
private FakeFeatureFactory mFactory;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
+ mBatteryManager = mContext.getSystemService(BatteryManager.class);
+ mShadowBatteryManager = shadowOf(mBatteryManager);
mFactory = FakeFeatureFactory.setupForTest();
mController = new BatteryFirstUseDatePreferenceController(mContext,
"battery_info_first_use_date");
@@ -50,15 +60,37 @@ public class BatteryFirstUseDatePreferenceControllerTest {
@Test
public void getAvailabilityStatus_dateAvailable_returnAvailable() {
- when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable()).thenReturn(true);
+ when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable(anyLong()))
+ .thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_dateUnavailable_returnNotAvailable() {
- when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable()).thenReturn(false);
+ when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable(anyLong()))
+ .thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
+
+ @Test
+ public void getSummary_available_returnExpectedDate() {
+ when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable(anyLong()))
+ .thenReturn(true);
+ mShadowBatteryManager.setLongProperty(BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE,
+ 1669680000L);
+
+ final CharSequence result = mController.getSummary();
+
+ assertThat(result.toString()).isEqualTo("November 29, 2022");
+ }
+
+ @Test
+ public void getSummary_unavailable_returnNull() {
+ when(mFactory.batterySettingsFeatureProvider.isFirstUseDateAvailable(anyLong()))
+ .thenReturn(false);
+
+ assertThat(mController.getSummary()).isNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceControllerTest.java
index c4a5486b259..fed74f3a8f9 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/batteryinfo/BatteryManufactureDatePreferenceControllerTest.java
@@ -21,9 +21,12 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
+import android.os.BatteryManager;
import androidx.test.core.app.ApplicationProvider;
@@ -33,17 +36,24 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowBatteryManager;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBatteryManager.class})
public class BatteryManufactureDatePreferenceControllerTest {
private BatteryManufactureDatePreferenceController mController;
private Context mContext;
+ private BatteryManager mBatteryManager;
+ private ShadowBatteryManager mShadowBatteryManager;
private FakeFeatureFactory mFactory;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
+ mBatteryManager = mContext.getSystemService(BatteryManager.class);
+ mShadowBatteryManager = shadowOf(mBatteryManager);
mFactory = FakeFeatureFactory.setupForTest();
mController = new BatteryManufactureDatePreferenceController(mContext,
"battery_info_manufacture_date");
@@ -51,16 +61,37 @@ public class BatteryManufactureDatePreferenceControllerTest {
@Test
public void getAvailabilityStatus_dateAvailable_returnAvailable() {
- when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable()).thenReturn(true);
+ when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable(
+ anyLong())).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_dateUnavailable_returnNotAvailable() {
- when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable())
+ when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable(anyLong()))
.thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
+
+ @Test
+ public void getSummary_available_returnExpectedDate() {
+ when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable(
+ anyLong())).thenReturn(true);
+ mShadowBatteryManager.setLongProperty(BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE,
+ 1669680000L);
+
+ final CharSequence result = mController.getSummary();
+
+ assertThat(result.toString()).isEqualTo("November 29, 2022");
+ }
+
+ @Test
+ public void getSummary_unavailable_returnNull() {
+ when(mFactory.batterySettingsFeatureProvider.isManufactureDateAvailable(anyLong()))
+ .thenReturn(false);
+
+ assertThat(mController.getSummary()).isNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
index dfef3c7f0b8..6c0912561b2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
@@ -18,83 +18,29 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.robolectric.Shadows.shadowOf;
-
-import android.content.Context;
-import android.os.BatteryManager;
-
-import androidx.test.core.app.ApplicationProvider;
+import static org.mockito.ArgumentMatchers.anyLong;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowBatteryManager;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowBatteryManager.class})
public class BatterySettingsFeatureProviderImplTest {
- private BatteryManager mBatteryManager;
- private ShadowBatteryManager mShadowBatteryManager;
- private Context mContext;
private BatterySettingsFeatureProviderImpl mImpl;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(ApplicationProvider.getApplicationContext());
- mBatteryManager = mContext.getSystemService(BatteryManager.class);
- mShadowBatteryManager = shadowOf(mBatteryManager);
- mImpl = spy(new BatterySettingsFeatureProviderImpl(mContext));
+ mImpl = new BatterySettingsFeatureProviderImpl();
}
@Test
public void isManufactureDateAvailable_returnFalse() {
- assertThat(mImpl.isManufactureDateAvailable()).isFalse();
+ assertThat(mImpl.isManufactureDateAvailable(anyLong())).isFalse();
}
@Test
public void isFirstUseDateAvailable_returnFalse() {
- assertThat(mImpl.isFirstUseDateAvailable()).isFalse();
- }
-
- @Test
- public void getManufactureDateSummary_available_returnExpectedDate() {
- doReturn(true).when(mImpl).isManufactureDateAvailable();
- mShadowBatteryManager.setLongProperty(BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE,
- 1669680000L);
-
- final CharSequence result = mImpl.getManufactureDateSummary();
-
- assertThat(result.toString()).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();
- mShadowBatteryManager.setLongProperty(BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE,
- 1669680000L);
-
- final CharSequence result = mImpl.getFirstUseDateSummary();
-
- assertThat(result.toString()).isEqualTo("November 29, 2022");
- }
-
- @Test
- public void getFirstUseDateSummary_unavailable_returnNull() {
- doReturn(false).when(mImpl).isFirstUseDateAvailable();
-
- assertThat(mImpl.getFirstUseDateSummary()).isNull();
+ assertThat(mImpl.isFirstUseDateAvailable(anyLong())).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 47053802e39..fcb01b4649e 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -31,6 +31,8 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -171,7 +173,7 @@ public class FakeFeatureFactory extends FeatureFactory {
}
@Override
- public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider(Context context) {
+ public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider() {
return batterySettingsFeatureProvider;
}
@@ -290,6 +292,11 @@ public class FakeFeatureFactory extends FeatureFactory {
return mAccessibilityMetricsFeatureProvider;
}
+ @Override
+ public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() {
+ return HardwareInfoFeatureProviderImpl.INSTANCE;
+ }
+
@Override
public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() {
return mAdvancedVpnFeatureProvider;
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 50589ac67e0..68078f8ba56 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.biometrics2.factory.BiometricsRepositoryProvider
import com.android.settings.bluetooth.BluetoothFeatureProvider
import com.android.settings.dashboard.DashboardFeatureProvider
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
@@ -84,9 +85,7 @@ class FakeFeatureFactory : FeatureFactory() {
TODO("Not yet implemented")
}
- override fun getBatterySettingsFeatureProvider(
- context: Context?,
- ): BatterySettingsFeatureProvider {
+ override fun getBatterySettingsFeatureProvider(): BatterySettingsFeatureProvider {
TODO("Not yet implemented")
}
@@ -176,6 +175,10 @@ class FakeFeatureFactory : FeatureFactory() {
TODO("Not yet implemented")
}
+ override fun getHardwareInfoFeatureProvider(): HardwareInfoFeatureProvider {
+ TODO("Not yet implemented")
+ }
+
override fun getAdvancedVpnFeatureProvider(): AdvancedVpnFeatureProvider {
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 d7490100990..7a498652a5d 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -29,6 +29,8 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
+import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -157,7 +159,7 @@ public class FakeFeatureFactory extends FeatureFactory {
}
@Override
- public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider(Context context) {
+ public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider() {
return batterySettingsFeatureProvider;
}
@@ -276,6 +278,11 @@ public class FakeFeatureFactory extends FeatureFactory {
return mAccessibilityMetricsFeatureProvider;
}
+ @Override
+ public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() {
+ return HardwareInfoFeatureProviderImpl.INSTANCE;
+ }
+
@Override
public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() {
return mAdvancedVpnFeatureProvider;