Snap for 10309372 from cc1fe61339 to udc-qpr1-release
Change-Id: Ie27537a8c5667957554f870e1cd29e317478dde4
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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] -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 ?: ""
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user