Snap for 10309372 from cc1fe61339 to udc-qpr1-release

Change-Id: Ie27537a8c5667957554f870e1cd29e317478dde4
This commit is contained in:
Android Build Coastguard Worker
2023-06-13 03:19:30 +00:00
29 changed files with 480 additions and 226 deletions

View File

@@ -2397,6 +2397,7 @@
<intent-filter android:priority="1">
<action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL" />
<action android:name="android.app.action.CONFIRM_FRP_CREDENTIAL" />
<action android:name="android.app.action.PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

View File

@@ -131,7 +131,7 @@
<!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
<string name="bluetooth_device_controls_title">Hearing device settings</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
<string name="bluetooth_device_controls_summary">Audio output, shortcut, hearing aid compatibility</string>
<string name="bluetooth_device_controls_summary">Shortcut, hearing aid compatibility</string>
<!-- Title for this device specific controls section. [CHAR LIMIT=30] -->
<string name="bluetooth_device_controls_specific">For this device</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the audio output page. It can change different types of audio are played on phone or other bluetooth devices. [CHAR LIMIT=35] -->
@@ -2648,6 +2648,8 @@
<string name="model_info">Model</string>
<!-- Label for device's hardware revision value [CHAR LIMIT=40] -->
<string name="hardware_revision">Hardware version</string>
<!-- Label for device's manufactured year value [CHAR LIMIT=40] -->
<string name="manufactured_year">Manufactured year</string>
<!-- About phone screen, fcc equipment id label [CHAR LIMIT=40] -->
<string name="fcc_equipment_id">Equipment ID</string>
<!-- About phone screen, setting option name [CHAR LIMIT=40] -->

View File

@@ -48,4 +48,13 @@
settings:controller="com.android.settings.deviceinfo.hardwareinfo.HardwareRevisionPreferenceController"
settings:enableCopying="true"/>
<!-- Manufactured year -->
<Preference
android:key="hardware_info_manufactured_year"
android:title="@string/manufactured_year"
android:summary="@string/summary_placeholder"
android:selectable="false"
settings:controller="com.android.settings.deviceinfo.hardwareinfo.ManufacturedYearPreferenceController"
settings:enableCopying="true"/>
</PreferenceScreen>

View File

@@ -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<count; i++) {
for (int i = 0; i < count; i++) {
ResolveInfo ri = avail.get(i);
if (ai.packageName.equals(ri.activityInfo.packageName)
&& ai.name.equals(ri.activityInfo.name)) {
@@ -345,21 +346,21 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
mAdminWarning.setText(
mDPM.getResources().getString(NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED, () ->
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);
}
/**

View File

@@ -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()) {

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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?
}

View File

@@ -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
}

View File

@@ -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 ?: ""
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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<Class<?>> 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,

View File

@@ -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)) {

View File

@@ -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(),

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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<Face> 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);
}
}

View File

@@ -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<CancellationSignal> mCancellationSignalArgumentCaptor =
ArgumentCaptor.forClass(CancellationSignal.class);
@Captor
private ArgumentCaptor<FingerprintManager.AuthenticationCallback>
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();

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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")
}

View File

@@ -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;