diff options
369 files changed, 4757 insertions, 2348 deletions
diff --git a/Android.bp b/Android.bp index 08efa8ee72ed..3af2f07884e5 100644 --- a/Android.bp +++ b/Android.bp @@ -296,6 +296,7 @@ java_defaults { ], include_dirs: [ "frameworks/av/aidl", + "frameworks/native/libs/permission/aidl", "packages/modules/Connectivity/framework/aidl-export", ], }, @@ -537,6 +538,7 @@ stubs_defaults { ], include_dirs: [ "frameworks/av/aidl", + "frameworks/native/libs/permission/aidl", "packages/modules/Connectivity/framework/aidl-export", ], }, diff --git a/ApiDocs.bp b/ApiDocs.bp index 0aed5d9abea9..aae4a7174d68 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -113,7 +113,10 @@ stubs_defaults { // TODO(b/169090544): remove below aidl includes. aidl: { local_include_dirs: ["media/aidl"], - include_dirs: ["frameworks/av/aidl"], + include_dirs: [ + "frameworks/av/aidl", + "frameworks/native/libs/permission/aidl", + ], }, } @@ -199,7 +202,10 @@ doc_defaults { // TODO(b/169090544): remove below aidl includes. aidl: { local_include_dirs: ["media/aidl"], - include_dirs: ["frameworks/av/aidl"], + include_dirs: [ + "frameworks/av/aidl", + "frameworks/native/libs/permission/aidl", + ], }, } diff --git a/StubLibraries.bp b/StubLibraries.bp index 941a1fa033e4..44c55c26153d 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -410,7 +410,7 @@ java_library { ], static_libs: [ "android-non-updatable.stubs.module_lib", - "art.module.public.api.stubs", + "art.module.public.api.stubs.module_lib", ], dist: { dir: "apistubs/android/module-lib", diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 86fa06cdb8dc..95728081bdb9 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -2603,7 +2603,7 @@ public class AlarmManagerService extends SystemService { final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); if (callingUid != uid && !UserHandle.isCore(callingUid)) { throw new SecurityException("Uid " + callingUid - + " cannot query hasScheduleExactAlarm for uid " + uid); + + " cannot query hasScheduleExactAlarm for package " + packageName); } return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false; } diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 78670c7c73b1..591e8ba859fc 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -690,7 +690,6 @@ public class JobSchedulerService extends com.android.server.SystemService @VisibleForTesting class PendingJobComparator implements Comparator<JobStatus> { - private final SparseBooleanArray mUidHasEjCache = new SparseBooleanArray(); private final SparseLongArray mEarliestRegEnqueueTimeCache = new SparseLongArray(); /** @@ -699,14 +698,11 @@ public class JobSchedulerService extends com.android.server.SystemService @GuardedBy("mLock") @VisibleForTesting void refreshLocked() { - mUidHasEjCache.clear(); mEarliestRegEnqueueTimeCache.clear(); for (int i = 0; i < mPendingJobs.size(); ++i) { final JobStatus job = mPendingJobs.get(i); final int uid = job.getSourceUid(); - if (job.isRequestedExpeditedJob()) { - mUidHasEjCache.put(uid, true); - } else { + if (!job.isRequestedExpeditedJob()) { final long earliestEnqueueTime = mEarliestRegEnqueueTimeCache.get(uid, Long.MAX_VALUE); mEarliestRegEnqueueTimeCache.put(uid, @@ -736,9 +732,7 @@ public class JobSchedulerService extends com.android.server.SystemService return o1EJ ? -1 : 1; } } - final boolean uid1HasEj = mUidHasEjCache.get(o1.getSourceUid()); - final boolean uid2HasEj = mUidHasEjCache.get(o2.getSourceUid()); - if ((uid1HasEj || uid2HasEj) && (o1EJ || o2EJ)) { + if (o1EJ || o2EJ) { // We MUST prioritize EJs ahead of regular jobs within a single app. Since we do // that, in order to satisfy the transitivity constraint of the comparator, if // any UID has an EJ, we must ensure that the EJ is ordered ahead of the regular @@ -759,9 +753,13 @@ public class JobSchedulerService extends com.android.server.SystemService } else if (uid1EarliestRegEnqueueTime > uid2EarliestRegEnqueueTime) { return 1; } - } else if (o1EJ && uid1EarliestRegEnqueueTime < o2.enqueueTime) { + } else if (o1EJ && uid1EarliestRegEnqueueTime <= o2.enqueueTime) { + // Include = to ensure that if we sorted an EJ ahead of a regular job at time X + // then we make sure to sort it ahead of all regular jobs at time X. return -1; - } else if (o2EJ && uid2EarliestRegEnqueueTime < o1.enqueueTime) { + } else if (o2EJ && uid2EarliestRegEnqueueTime <= o1.enqueueTime) { + // Include = to ensure that if we sorted an EJ ahead of a regular job at time X + // then we make sure to sort it ahead of all regular jobs at time X. return 1; } } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index a0799394177d..ea6d0cecfd73 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3176,7 +3176,6 @@ package android.window { public final class SplashScreenView extends android.widget.FrameLayout { method @Nullable public android.view.View getBrandingView(); - method @ColorInt public int getIconBackgroundColor(); } public final class StartingWindowInfo implements android.os.Parcelable { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3915abe1e9eb..dbaf2757a9e2 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -369,11 +369,12 @@ public final class ActivityThread extends ClientTransactionHandler @UnsupportedAppUsage(trackingBug = 176961850, maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@code Context#getResources()#getConfiguration()} instead.") Configuration mConfiguration; + @GuardedBy("this") + private boolean mUpdateHttpProxyOnBind = false; @UnsupportedAppUsage Application mInitialApplication; @UnsupportedAppUsage - final ArrayList<Application> mAllApplications - = new ArrayList<Application>(); + final ArrayList<Application> mAllApplications = new ArrayList<>(); /** * Bookkeeping of instantiated backup agents indexed first by user id, then by package name. * Indexing by user id supports parallel backups across users on system packages as they run in @@ -1187,8 +1188,18 @@ public final class ActivityThread extends ClientTransactionHandler } public void updateHttpProxy() { - ActivityThread.updateHttpProxy( - getApplication() != null ? getApplication() : getSystemContext()); + final Application app; + synchronized (ActivityThread.this) { + app = getApplication(); + if (null == app) { + // The app is not bound yet. Make a note to update the HTTP proxy when the + // app is bound. + mUpdateHttpProxyOnBind = true; + return; + } + } + // App is present, update the proxy inline. + ActivityThread.updateHttpProxy(app); } public void processInBackground() { @@ -6685,6 +6696,15 @@ public final class ActivityThread extends ClientTransactionHandler sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName); mInitialApplication = app; + final boolean updateHttpProxy; + synchronized (this) { + updateHttpProxy = mUpdateHttpProxyOnBind; + // This synchronized block ensures that any subsequent call to updateHttpProxy() + // will see a non-null mInitialApplication. + } + if (updateHttpProxy) { + ActivityThread.updateHttpProxy(app); + } // don't bring up providers in restricted mode; they may depend on the // app's custom Application class diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 9d149cf340e2..4b054f49d910 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6122,28 +6122,29 @@ public class Notification implements Parcelable // change the background bgColor CharSequence title = action.title; ColorStateList[] outResultColor = new ColorStateList[1]; - int background = getColors(p).getSecondaryAccentColor(); + int buttonFillColor = getColors(p).getSecondaryAccentColor(); if (isLegacy()) { title = ContrastColorUtil.clearColorSpans(title); } else { - title = ensureColorSpanContrast(title, background, outResultColor); + int notifBackgroundColor = getColors(p).getBackgroundColor(); + title = ensureColorSpanContrast(title, notifBackgroundColor, outResultColor); } button.setTextViewText(R.id.action0, processTextSpans(title)); boolean hasColorOverride = outResultColor[0] != null; if (hasColorOverride) { // There's a span spanning the full text, let's take it and use it as the // background color - background = outResultColor[0].getDefaultColor(); + buttonFillColor = outResultColor[0].getDefaultColor(); } final int textColor = ContrastColorUtil.resolvePrimaryColor(mContext, - background, mInNightMode); + buttonFillColor, mInNightMode); button.setTextColor(R.id.action0, textColor); // We only want about 20% alpha for the ripple final int rippleColor = (textColor & 0x00ffffff) | 0x33000000; button.setColorStateList(R.id.action0, "setRippleColor", ColorStateList.valueOf(rippleColor)); button.setColorStateList(R.id.action0, "setButtonBackground", - ColorStateList.valueOf(background)); + ColorStateList.valueOf(buttonFillColor)); if (p.mCallStyleActions) { button.setImageViewIcon(R.id.action0, action.getIcon()); boolean priority = action.getExtras().getBoolean(CallStyle.KEY_ACTION_PRIORITY); @@ -6176,8 +6177,8 @@ public class Notification implements Parcelable * there exists a full length color span. * @return the contrasted charSequence */ - private CharSequence ensureColorSpanContrast(CharSequence charSequence, int background, - ColorStateList[] outResultColor) { + private static CharSequence ensureColorSpanContrast(CharSequence charSequence, + int background, ColorStateList[] outResultColor) { if (charSequence instanceof Spanned) { Spanned ss = (Spanned) charSequence; Object[] spans = ss.getSpans(0, ss.length(), Object.class); @@ -6197,8 +6198,9 @@ public class Notification implements Parcelable int[] colors = textColor.getColors(); int[] newColors = new int[colors.length]; for (int i = 0; i < newColors.length; i++) { + boolean isBgDark = isColorDark(background); newColors[i] = ContrastColorUtil.ensureLargeTextContrast( - colors[i], background, mInNightMode); + colors[i], background, isBgDark); } textColor = new ColorStateList(textColor.getStates().clone(), newColors); @@ -6217,8 +6219,9 @@ public class Notification implements Parcelable } else if (resultSpan instanceof ForegroundColorSpan) { ForegroundColorSpan originalSpan = (ForegroundColorSpan) resultSpan; int foregroundColor = originalSpan.getForegroundColor(); + boolean isBgDark = isColorDark(background); foregroundColor = ContrastColorUtil.ensureLargeTextContrast( - foregroundColor, background, mInNightMode); + foregroundColor, background, isBgDark); if (fullLength) { outResultColor[0] = ColorStateList.valueOf(foregroundColor); resultSpan = null; @@ -6238,6 +6241,19 @@ public class Notification implements Parcelable } /** + * Determines if the color is light or dark. Specifically, this is using the same metric as + * {@link ContrastColorUtil#resolvePrimaryColor(Context, int, boolean)} and peers so that + * the direction of color shift is consistent. + * + * @param color the color to check + * @return true if the color has higher contrast with white than black + */ + private static boolean isColorDark(int color) { + // as per ContrastColorUtil.shouldUseDark, this uses the color contrast midpoint. + return ContrastColorUtil.calculateLuminance(color) <= 0.17912878474; + } + + /** * @return Whether we are currently building a notification from a legacy (an app that * doesn't create material notifications by itself) app. */ diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 549ab6e2df83..0e04ad3768c7 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -10997,6 +10997,16 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT} in the provisioning parameters. * In that case the device owner's control will be limited do denying these permissions. * <p> + * NOTE: On devices running {@link android.os.Build.VERSION_CODES#S} and above, control over + * the following permissions are restricted for managed profile owners: + * <ul> + * <li>Manifest.permission.READ_SMS</li> + * </ul> + * <p> + * A managed profile owner may not grant these permissions (i.e. call this method with any of + * the permissions listed above and {@code grantState} of + * {@code #PERMISSION_GRANT_STATE_GRANTED}), but may deny them. + * <p> * Attempts by the admin to grant these permissions, when the admin is restricted from doing * so, will be silently ignored (no exception will be thrown). * diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java index 5694ca860453..266e33af0e22 100644 --- a/core/java/android/appwidget/AppWidgetManagerInternal.java +++ b/core/java/android/appwidget/AppWidgetManagerInternal.java @@ -19,6 +19,8 @@ package android.appwidget; import android.annotation.Nullable; import android.util.ArraySet; +import java.util.Set; + /** * App widget manager local system service interface. * @@ -42,4 +44,16 @@ public abstract class AppWidgetManagerInternal { * @param userId The user that is being unlocked. */ public abstract void unlockUser(int userId); + + /** + * Updates all widgets, applying changes to Runtime Resource Overlay affecting the specified + * target packages. + * + * @param packageNames The names of all target packages for which an overlay was modified + * @param userId The user for which overlay modifications occurred. + * @param updateFrameworkRes Whether or not an overlay affected the values of framework + * resources. + */ + public abstract void applyResourceOverlaysToWidgets(Set<String> packageNames, int userId, + boolean updateFrameworkRes); } diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 65cdca9eb7d8..1dd32fec2510 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -1025,6 +1025,10 @@ public final class BluetoothA2dp implements BluetoothProfile { public boolean setBufferLengthMillis(@BluetoothCodecConfig.SourceCodecType int codec, int value) { if (VDBG) log("setBufferLengthMillis(" + codec + ", " + value + ")"); + if (value < 0) { + Log.e(TAG, "Trying to set audio buffer length to a negative value: " + value); + return false; + } try { final IBluetoothA2dp service = getService(); if (service != null && isEnabled()) { diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java index cb3bf297670f..8ff018121ab0 100644 --- a/core/java/android/bluetooth/le/ScanFilter.java +++ b/core/java/android/bluetooth/le/ScanFilter.java @@ -168,6 +168,15 @@ public final class ScanFilter implements Parcelable { dest.writeByteArray(mManufacturerDataMask); } } + + // IRK + if (mDeviceAddress != null) { + dest.writeInt(mAddressType); + dest.writeInt(mIrk == null ? 0 : 1); + if (mIrk != null) { + dest.writeByteArray(mIrk); + } + } } /** @@ -187,8 +196,10 @@ public final class ScanFilter implements Parcelable { if (in.readInt() == 1) { builder.setDeviceName(in.readString()); } + String address = null; + // If we have a non-null address if (in.readInt() == 1) { - builder.setDeviceAddress(in.readString()); + address = in.readString(); } if (in.readInt() == 1) { ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader()); @@ -245,6 +256,17 @@ public final class ScanFilter implements Parcelable { } } + // IRK + if (address != null) { + final int addressType = in.readInt(); + if (in.readInt() == 1) { + final byte[] irk = new byte[16]; + in.readByteArray(irk); + builder.setDeviceAddress(address, addressType, irk); + } else { + builder.setDeviceAddress(address, addressType); + } + } return builder.build(); } }; diff --git a/core/java/android/content/pm/PackageParserCacheHelper.java b/core/java/android/content/pm/PackageParserCacheHelper.java index 8212224e114c..e03c3ee4fab9 100644 --- a/core/java/android/content/pm/PackageParserCacheHelper.java +++ b/core/java/android/content/pm/PackageParserCacheHelper.java @@ -56,6 +56,9 @@ public class PackageParserCacheHelper { mStrings.clear(); final int poolPosition = mParcel.readInt(); + if (poolPosition < 0) { + throw new IllegalStateException("Invalid string pool position: " + poolPosition); + } final int startPosition = mParcel.dataPosition(); // The pool is at the end of the parcel. diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java index 4526ab770bc6..fa7ce11c5414 100644 --- a/core/java/android/hardware/SensorPrivacyManager.java +++ b/core/java/android/hardware/SensorPrivacyManager.java @@ -24,12 +24,12 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UserIdInt; -import android.app.ActivityManager; import android.content.Context; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.service.SensorPrivacyIndividualEnabledSensorProto; import android.service.SensorPrivacyToggleSourceProto; import android.util.ArrayMap; @@ -379,7 +379,7 @@ public final class SensorPrivacyManager { @SystemApi @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) { - return isSensorPrivacyEnabled(sensor, getCurrentUserId()); + return isSensorPrivacyEnabled(sensor, UserHandle.USER_CURRENT); } /** @@ -410,7 +410,7 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, boolean enable) { - setSensorPrivacy(source, sensor, enable, getCurrentUserId()); + setSensorPrivacy(source, sensor, enable, UserHandle.USER_CURRENT); } /** @@ -446,7 +446,7 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacyForProfileGroup(@Sources.Source int source, @Sensors.Sensor int sensor, boolean enable) { - setSensorPrivacyForProfileGroup(source , sensor, enable, getCurrentUserId()); + setSensorPrivacyForProfileGroup(source , sensor, enable, UserHandle.USER_CURRENT); } /** @@ -481,7 +481,7 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void suppressSensorPrivacyReminders(int sensor, boolean suppress) { - suppressSensorPrivacyReminders(sensor, suppress, getCurrentUserId()); + suppressSensorPrivacyReminders(sensor, suppress, UserHandle.USER_CURRENT); } /** @@ -609,12 +609,4 @@ public final class SensorPrivacyManager { } } - private int getCurrentUserId() { - try { - return ActivityManager.getService().getCurrentUserId(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - return 0; - } } diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index c78dd5366d31..b55a1cbe0bed 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -2318,6 +2318,51 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> new Key<Float>("android.control.zoomRatio", float.class); /** + * <p>Framework-only private key which informs camera fwk that the AF regions has been set + * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is + * set to MAXIMUM_RESOLUTION.</p> + * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets + * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p> + * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> + * + * @see CaptureRequest#CONTROL_AF_REGIONS + * @see CaptureRequest#SENSOR_PIXEL_MODE + * @hide + */ + public static final Key<Boolean> CONTROL_AF_REGIONS_SET = + new Key<Boolean>("android.control.afRegionsSet", boolean.class); + + /** + * <p>Framework-only private key which informs camera fwk that the AE regions has been set + * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is + * set to MAXIMUM_RESOLUTION.</p> + * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets + * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}.</p> + * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> + * + * @see CaptureRequest#CONTROL_AE_REGIONS + * @see CaptureRequest#SENSOR_PIXEL_MODE + * @hide + */ + public static final Key<Boolean> CONTROL_AE_REGIONS_SET = + new Key<Boolean>("android.control.aeRegionsSet", boolean.class); + + /** + * <p>Framework-only private key which informs camera fwk that the AF regions has been set + * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is + * set to MAXIMUM_RESOLUTION.</p> + * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets + * {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}.</p> + * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> + * + * @see CaptureRequest#CONTROL_AWB_REGIONS + * @see CaptureRequest#SENSOR_PIXEL_MODE + * @hide + */ + public static final Key<Boolean> CONTROL_AWB_REGIONS_SET = + new Key<Boolean>("android.control.awbRegionsSet", boolean.class); + + /** * <p>Operation mode for edge * enhancement.</p> * <p>Edge enhancement improves sharpness and details in the captured image. OFF means @@ -3057,6 +3102,21 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> new Key<Integer>("android.scaler.rotateAndCrop", int.class); /** + * <p>Framework-only private key which informs camera fwk that the scaler crop region + * ({@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}) has been set by the client and it need + * not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to MAXIMUM_RESOLUTION.</p> + * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets + * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}.</p> + * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> + * + * @see CaptureRequest#SCALER_CROP_REGION + * @see CaptureRequest#SENSOR_PIXEL_MODE + * @hide + */ + public static final Key<Boolean> SCALER_CROP_REGION_SET = + new Key<Boolean>("android.scaler.cropRegionSet", boolean.class); + + /** * <p>Duration each pixel is exposed to * light.</p> * <p>If the sensor can't expose this exact duration, it will shorten the diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java index bfc1f2765c3b..d5a35bc31e68 100644 --- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java @@ -446,10 +446,16 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } } - public void release() { - synchronized (mInterfaceLock) { + @Override + protected void finalize() throws Throwable { + if (mHandlerThread != null) { mHandlerThread.quitSafely(); + } + super.finalize(); + } + public void release() { + synchronized (mInterfaceLock) { if (mSessionProcessor != null) { try { mSessionProcessor.deInitSession(); @@ -812,6 +818,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes Log.e(TAG,"Failed to parcel buffer fence!"); } } + parcelImage.width = img.getWidth(); + parcelImage.height = img.getHeight(); parcelImage.format = img.getFormat(); parcelImage.timestamp = img.getTimestamp(); parcelImage.transform = img.getTransform(); diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 11b137ca01f3..0bf812e03984 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -696,6 +696,16 @@ public class CameraDeviceImpl extends CameraDevice mCurrentSession.replaceSessionClose(); } + if (mCurrentExtensionSession != null) { + mCurrentExtensionSession.release(); + mCurrentExtensionSession = null; + } + + if (mCurrentAdvancedExtensionSession != null) { + mCurrentAdvancedExtensionSession.release(); + mCurrentAdvancedExtensionSession = null; + } + // TODO: dont block for this boolean configureSuccess = true; CameraAccessException pendingException = null; diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java index 537b894d9a6a..7d29a7d275cf 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java @@ -49,8 +49,6 @@ import android.media.ImageWriter; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; -import android.os.IBinder; -import android.os.IInterface; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.annotation.NonNull; @@ -265,13 +263,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { } catch (ClassCastException e) { throw new UnsupportedOperationException("Failed casting preview processor!"); } - if (mClientRepeatingRequestSurface != null) { - mPreviewRequestUpdateProcessor.onOutputSurface(mClientRepeatingRequestSurface, - nativeGetSurfaceFormat(mClientRepeatingRequestSurface)); - mRepeatingRequestImageWriter = ImageWriter.newInstance( - mClientRepeatingRequestSurface, PREVIEW_QUEUE_SIZE, - CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT); - } mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth, repeatingSurfaceInfo.mHeight, CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT, @@ -285,11 +276,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { mPreviewRequestUpdateProcessor.onImageFormatUpdate( CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT); } else { - if (mClientRepeatingRequestSurface != null) { - mRepeatingRequestImageWriter = ImageWriter.newInstance( - mClientRepeatingRequestSurface, PREVIEW_QUEUE_SIZE, - CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT); - } mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth, repeatingSurfaceInfo.mHeight, CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT, @@ -320,7 +306,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { mBurstCaptureImageReader = ImageReader.newInstance(surfaceInfo.mWidth, surfaceInfo.mHeight, CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, mImageExtender.getMaxCaptureStage()); - mImageProcessor.onOutputSurface(mClientCaptureSurface, surfaceInfo.mFormat); } else { // The client doesn't intend to trigger multi-frame capture, however the // image extender still needs to get initialized and the camera still capture @@ -367,6 +352,29 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { } } + private void finishPipelineInitialization() throws RemoteException { + if (mClientRepeatingRequestSurface != null) { + if (mPreviewProcessorType == IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY) { + mPreviewRequestUpdateProcessor.onOutputSurface(mClientRepeatingRequestSurface, + nativeGetSurfaceFormat(mClientRepeatingRequestSurface)); + mRepeatingRequestImageWriter = ImageWriter.newInstance( + mClientRepeatingRequestSurface, + PREVIEW_QUEUE_SIZE, + CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT); + } else if (mPreviewProcessorType == IPreviewExtenderImpl.PROCESSOR_TYPE_NONE) { + mRepeatingRequestImageWriter = ImageWriter.newInstance( + mClientRepeatingRequestSurface, + PREVIEW_QUEUE_SIZE, + CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT); + } + } + if ((mImageProcessor != null) && (mClientCaptureSurface != null)) { + CameraExtensionUtils.SurfaceInfo surfaceInfo = CameraExtensionUtils.querySurface( + mClientCaptureSurface); + mImageProcessor.onOutputSurface(mClientCaptureSurface, surfaceInfo.mFormat); + } + } + /** * @hide */ @@ -622,11 +630,18 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { new CameraExtensionUtils.HandlerExecutor(mHandler), requestHandler); } + @Override + protected void finalize() throws Throwable { + if (mHandlerThread != null) { + mHandlerThread.quitSafely(); + } + super.finalize(); + } + /** @hide */ public void release() { synchronized (mInterfaceLock) { mInternalRepeatingRequestEnabled = false; - mHandlerThread.quitSafely(); try { mPreviewExtender.onDeInit(); @@ -750,6 +765,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { synchronized (mInterfaceLock) { mCaptureSession = session; try { + finishPipelineInitialization(); CameraExtensionCharacteristics.initializeSession(mInitializeHandler); } catch (RemoteException e) { Log.e(TAG, "Failed to initialize session! Extension service does" @@ -1640,6 +1656,8 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { Log.e(TAG,"Failed to parcel buffer fence!"); } } + parcelImage.width = img.getWidth(); + parcelImage.height = img.getHeight(); parcelImage.format = img.getFormat(); parcelImage.timestamp = img.getTimestamp(); parcelImage.transform = img.getTransform(); diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java index 950d716b05e8..9acf9bf0c803 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.ImageFormat; import android.graphics.PixelFormat; -import android.hardware.HardwareBuffer; import android.hardware.camera2.CameraExtensionCharacteristics; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; @@ -78,41 +77,20 @@ public final class CameraExtensionUtils { SurfaceInfo surfaceInfo = new SurfaceInfo(); int nativeFormat = SurfaceUtils.getSurfaceFormat(s); int dataspace = SurfaceUtils.getSurfaceDataspace(s); + Size surfaceSize = SurfaceUtils.getSurfaceSize(s); + surfaceInfo.mFormat = nativeFormat; + surfaceInfo.mWidth = surfaceSize.getWidth(); + surfaceInfo.mHeight = surfaceSize.getHeight(); + surfaceInfo.mUsage = SurfaceUtils.getSurfaceUsage(s); // Jpeg surfaces cannot be queried for their usage and other parameters // in the usual way below. A buffer can only be de-queued after the // producer overrides the surface dimensions to (width*height) x 1. if ((nativeFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) && (dataspace == StreamConfigurationMap.HAL_DATASPACE_V0_JFIF)) { surfaceInfo.mFormat = ImageFormat.JPEG; - Size surfaceSize = SurfaceUtils.getSurfaceSize(s); - surfaceInfo.mWidth = surfaceSize.getWidth(); - surfaceInfo.mHeight = surfaceSize.getHeight(); return surfaceInfo; } - HardwareBuffer buffer = null; - try { - writer = ImageWriter.newInstance(s, 1); - img = writer.dequeueInputImage(); - buffer = img.getHardwareBuffer(); - surfaceInfo.mFormat = buffer.getFormat(); - surfaceInfo.mWidth = buffer.getWidth(); - surfaceInfo.mHeight = buffer.getHeight(); - surfaceInfo.mUsage = buffer.getUsage(); - } catch (Exception e) { - Log.e(TAG, "Failed to query surface, returning defaults!"); - } finally { - if (buffer != null) { - buffer.close(); - } - if (img != null) { - img.close(); - } - if (writer != null) { - writer.close(); - } - } - return surfaceInfo; } diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 6cbe107c96f5..8fd9a6abf7b6 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -53,6 +53,7 @@ import android.hardware.camera2.params.Capability; import android.hardware.camera2.params.Face; import android.hardware.camera2.params.HighSpeedVideoConfiguration; import android.hardware.camera2.params.LensShadingMap; +import android.hardware.camera2.params.MeteringRectangle; import android.hardware.camera2.params.MandatoryStreamCombination; import android.hardware.camera2.params.MultiResolutionStreamConfigurationMap; import android.hardware.camera2.params.OisSample; @@ -1708,6 +1709,34 @@ public class CameraMetadataNative implements Parcelable { metadata.setGpsLocation((Location) value); } }); + sSetCommandMap.put(CaptureRequest.SCALER_CROP_REGION.getNativeKey(), + new SetCommand() { + @Override + public <T> void setValue(CameraMetadataNative metadata, T value) { + metadata.setScalerCropRegion((Rect) value); + } + }); + sSetCommandMap.put(CaptureRequest.CONTROL_AWB_REGIONS.getNativeKey(), + new SetCommand() { + @Override + public <T> void setValue(CameraMetadataNative metadata, T value) { + metadata.setAWBRegions((MeteringRectangle[]) value); + } + }); + sSetCommandMap.put(CaptureRequest.CONTROL_AF_REGIONS.getNativeKey(), + new SetCommand() { + @Override + public <T> void setValue(CameraMetadataNative metadata, T value) { + metadata.setAFRegions((MeteringRectangle[]) value); + } + }); + sSetCommandMap.put(CaptureRequest.CONTROL_AE_REGIONS.getNativeKey(), + new SetCommand() { + @Override + public <T> void setValue(CameraMetadataNative metadata, T value) { + metadata.setAERegions((MeteringRectangle[]) value); + } + }); } private boolean setAvailableFormats(int[] value) { @@ -1777,6 +1806,42 @@ public class CameraMetadataNative implements Parcelable { return true; } + private <T> boolean setScalerCropRegion(Rect cropRegion) { + if (cropRegion == null) { + return false; + } + setBase(CaptureRequest.SCALER_CROP_REGION_SET, true); + setBase(CaptureRequest.SCALER_CROP_REGION, cropRegion); + return true; + } + + private <T> boolean setAFRegions(MeteringRectangle[] afRegions) { + if (afRegions == null) { + return false; + } + setBase(CaptureRequest.CONTROL_AF_REGIONS_SET, true); + setBase(CaptureRequest.CONTROL_AF_REGIONS, afRegions); + return true; + } + + private <T> boolean setAERegions(MeteringRectangle[] aeRegions) { + if (aeRegions == null) { + return false; + } + setBase(CaptureRequest.CONTROL_AE_REGIONS_SET, true); + setBase(CaptureRequest.CONTROL_AE_REGIONS, aeRegions); + return true; + } + + private <T> boolean setAWBRegions(MeteringRectangle[] awbRegions) { + if (awbRegions == null) { + return false; + } + setBase(CaptureRequest.CONTROL_AWB_REGIONS_SET, true); + setBase(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions); + return true; + } + private void updateNativeAllocation() { long currentBufferSize = nativeGetBufferSize(mMetadataPtr); diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java index 35b5c1599070..57d8ded79e8e 100644 --- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java +++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java @@ -105,6 +105,20 @@ public class SurfaceUtils { } /** + * Get the surface usage bits. + * + * @param surface The surface to be queried for usage. + * @return the native object id of the surface, 0 if surface is not backed by a native object. + */ + public static long getSurfaceUsage(Surface surface) { + checkNotNull(surface); + try { + return nativeDetectSurfaceUsageFlags(surface); + } catch (IllegalArgumentException e) { + return 0; + } + } + /** * Get the Surface size. * * @param surface The surface to be queried for size. diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index c2a2c4c0678c..3c3ba595f3fb 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -169,31 +169,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } /** - * Request authentication of a crypto object. This call operates the face recognition hardware - * and starts capturing images. It terminates when - * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or - * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at - * which point the object is no longer valid. The operation can be canceled by using the - * provided cancel object. - * - * @param crypto object associated with the call or null if none required. - * @param cancel an object that can be used to cancel authentication - * @param callback an object to receive authentication events - * @param handler an optional handler to handle callback events - * @throws IllegalArgumentException if the crypto operation is not supported or is not backed - * by - * <a href="{@docRoot}training/articles/keystore.html">Android - * Keystore facility</a>. - * @throws IllegalStateException if the crypto primitive is not initialized. - * @hide - */ - @RequiresPermission(USE_BIOMETRIC_INTERNAL) - public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, - @NonNull AuthenticationCallback callback, @Nullable Handler handler) { - authenticate(crypto, cancel, callback, handler, mContext.getUserId()); - } - - /** * Use the provided handler thread for events. */ private void useHandler(Handler handler) { @@ -224,8 +199,10 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan * @throws IllegalStateException if the crypto primitive is not initialized. * @hide */ + @RequiresPermission(USE_BIOMETRIC_INTERNAL) public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, - @NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId) { + @NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId, + boolean isKeyguardBypassEnabled) { if (callback == null) { throw new IllegalArgumentException("Must supply an authentication callback"); } @@ -247,7 +224,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan final long operationId = crypto != null ? crypto.getOpId() : 0; Trace.beginSection("FaceManager#authenticate"); mService.authenticate(mToken, operationId, userId, mServiceReceiver, - mContext.getOpPackageName()); + mContext.getOpPackageName(), isKeyguardBypassEnabled); } catch (RemoteException e) { Slog.w(TAG, "Remote exception while authenticating: ", e); if (callback != null) { diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index b9a49c6ced09..db02a0ef2a10 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -46,7 +46,7 @@ interface IFaceService { // Authenticate the given sessionId with a face void authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver, - String opPackageName); + String opPackageName, boolean isKeyguardBypassEnabled); // Uses the face hardware to detect for the presence of a face, without giving details // about accept/reject/lockout. diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index f3e0ce9cd19e..1bc64951ad96 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -1460,15 +1460,15 @@ public final class FileUtils { /** {@hide} */ @VisibleForTesting public static ParcelFileDescriptor convertToModernFd(FileDescriptor fd) { - try { - Context context = AppGlobals.getInitialApplication(); - if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) { - // Never convert modern fd for MediaProvider, because this requires - // MediaStore#scanFile and can cause infinite loops when MediaProvider scans - return null; - } - return MediaStore.getOriginalMediaFormatFileDescriptor(context, - ParcelFileDescriptor.dup(fd)); + Context context = AppGlobals.getInitialApplication(); + if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) { + // Never convert modern fd for MediaProvider, because this requires + // MediaStore#scanFile and can cause infinite loops when MediaProvider scans + return null; + } + + try (ParcelFileDescriptor dupFd = ParcelFileDescriptor.dup(fd)) { + return MediaStore.getOriginalMediaFormatFileDescriptor(context, dupFd); } catch (Exception e) { Log.d(TAG, "Failed to convert to modern format file descriptor", e); return null; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 6bca336dae91..9f37c4877199 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -34,12 +34,9 @@ import dalvik.system.VMRuntime; import libcore.io.IoUtils; -import java.io.BufferedReader; import java.io.FileDescriptor; -import java.io.FileReader; import java.io.IOException; import java.util.Map; -import java.util.StringTokenizer; import java.util.concurrent.TimeoutException; /** @@ -1472,43 +1469,4 @@ public class Process { } private static native int nativePidFdOpen(int pid, int flags) throws ErrnoException; - - /** - * Checks if a process corresponding to a specific pid owns any file locks. - * @param pid The process ID for which we want to know the existence of file locks. - * @return true If the process holds any file locks, false otherwise. - * @throws IOException if /proc/locks can't be accessed. - * - * @hide - */ - public static boolean hasFileLocks(int pid) throws Exception { - BufferedReader br = null; - - try { - br = new BufferedReader(new FileReader("/proc/locks")); - String line; - - while ((line = br.readLine()) != null) { - StringTokenizer st = new StringTokenizer(line); - - for (int i = 0; i < 5 && st.hasMoreTokens(); i++) { - String str = st.nextToken(); - try { - if (i == 4 && Integer.parseInt(str) == pid) { - return true; - } - } catch (NumberFormatException nfe) { - throw new Exception("Exception parsing /proc/locks at \" " - + line + " \", token #" + i); - } - } - } - - return false; - } finally { - if (br != null) { - br.close(); - } - } - } } diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl index 9ab69552f1a0..4a94c32501a1 100644 --- a/core/java/android/permission/IPermissionManager.aidl +++ b/core/java/android/permission/IPermissionManager.aidl @@ -16,7 +16,7 @@ package android.permission; -import android.content.AttributionSource; +import android.content.AttributionSourceState; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; @@ -87,7 +87,7 @@ interface IPermissionManager { boolean isAutoRevokeExempted(String packageName, int userId); - void registerAttributionSource(in AttributionSource source); + void registerAttributionSource(in AttributionSourceState source); - boolean isRegisteredAttributionSource(in AttributionSource source); + boolean isRegisteredAttributionSource(in AttributionSourceState source); } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index a52ede87880e..63bcc9c89ca9 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -1177,7 +1177,7 @@ public final class PermissionManager { // enforcement we need to replace the binder with a unique one. final AttributionSource registeredSource = source.withToken(new Binder()); try { - mPermissionManager.registerAttributionSource(registeredSource); + mPermissionManager.registerAttributionSource(registeredSource.asState()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } @@ -1196,7 +1196,7 @@ public final class PermissionManager { */ public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) { try { - return mPermissionManager.isRegisteredAttributionSource(source); + return mPermissionManager.isRegisteredAttributionSource(source.asState()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 7a61511dfb4e..f4770727e31f 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -776,8 +776,10 @@ public abstract class WallpaperService extends Service { WallpaperColors color = colors.get(i); RectF area = regions.get(i); if (color == null || area == null) { - Log.wtf(TAG, "notifyLocalColorsChanged null values. color: " - + color + " area " + area); + if (DEBUG) { + Log.e(TAG, "notifyLocalColorsChanged null values. color: " + + color + " area " + area); + } continue; } try { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index f21d855ddcf9..6c2d6a1c3f2e 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -1242,7 +1242,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mBlastSurfaceControl.setTransformHint(mTransformHint); if (mBlastBufferQueue != null) { mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, - mFormat); + mFormat, transaction); } } else { transaction.setBufferSize(mSurfaceControl, mSurfaceWidth, mSurfaceHeight); diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 38019c9a34f8..5f036a348808 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -1013,8 +1013,10 @@ public interface InputConnection { * * @param imeConsumesInput {@code true} when the IME is consuming input and the cursor should be * hidden, {@code false} when input to the editor resumes and the cursor should be shown again. - * @return {@code true} on success, {@code false} if the input connection is no longer valid, or - * the protocol is not supported. + * @return For editor authors, the return value will always be ignored. For IME authors, this + * method returns {@code true} if the request was sent (whether or not the associated + * editor does something based on this request), {@code false} if the input connection + * is no longer valid. */ default boolean setImeConsumesInput(boolean imeConsumesInput) { return false; diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index e827f0a31bfd..91fc5a56d979 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -5824,6 +5824,25 @@ public class RemoteViews implements Parcelable, Filter { return false; } + /** @hide */ + public void updateAppInfo(@NonNull ApplicationInfo info) { + if (mApplication != null && mApplication.sourceDir.equals(info.sourceDir)) { + // Overlay paths are generated against a particular version of an application. + // The overlays paths of a newly upgraded application are incompatible with the + // old version of the application. + mApplication = info; + } + if (hasSizedRemoteViews()) { + for (RemoteViews layout : mSizedRemoteViews) { + layout.updateAppInfo(info); + } + } + if (hasLandscapeAndPortraitLayouts()) { + mLandscape.updateAppInfo(info); + mPortrait.updateAppInfo(info); + } + } + private Context getContextForResources(Context context) { if (mApplication != null) { if (context.getUserId() == UserHandle.getUserId(mApplication.uid) diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index 1efd2e381289..acf20d701eeb 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -89,11 +89,11 @@ public final class SplashScreenView extends FrameLayout { private boolean mNotCopyable; private boolean mIsCopied; private int mInitBackgroundColor; - private int mInitIconBackgroundColor; private View mIconView; private Bitmap mParceledIconBitmap; private View mBrandingImageView; private Bitmap mParceledBrandingBitmap; + private Bitmap mParceledIconBackgroundBitmap; private Duration mIconAnimationDuration; private Instant mIconAnimationStart; @@ -130,11 +130,12 @@ public final class SplashScreenView extends FrameLayout { private final Context mContext; private int mIconSize; private @ColorInt int mBackgroundColor; - private @ColorInt int mIconBackground; private Bitmap mParceledIconBitmap; + private Bitmap mParceledIconBackgroundBitmap; private Drawable mIconDrawable; // It is only set for legacy splash screen which won't be sent across processes. private Drawable mOverlayDrawable; + private Drawable mIconBackground; private SurfaceControlViewHost.SurfacePackage mSurfacePackage; private RemoteCallback mClientCallback; private int mBrandingImageWidth; @@ -155,7 +156,6 @@ public final class SplashScreenView extends FrameLayout { public Builder createFromParcel(SplashScreenViewParcelable parcelable) { mIconSize = parcelable.getIconSize(); mBackgroundColor = parcelable.getBackgroundColor(); - mIconBackground = parcelable.getIconBackground(); mSurfacePackage = parcelable.mSurfacePackage; if (mSurfacePackage == null && parcelable.mIconBitmap != null) { // We only create a Bitmap copies of immobile icons since animated icon are using @@ -163,6 +163,11 @@ public final class SplashScreenView extends FrameLayout { mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap); mParceledIconBitmap = parcelable.mIconBitmap; } + if (parcelable.mIconBackground != null) { + mIconBackground = new BitmapDrawable(mContext.getResources(), + parcelable.mIconBackground); + mParceledIconBackgroundBitmap = parcelable.mIconBackground; + } if (parcelable.mBrandingBitmap != null) { setBrandingDrawable(new BitmapDrawable(mContext.getResources(), parcelable.mBrandingBitmap), parcelable.mBrandingWidth, @@ -213,8 +218,8 @@ public final class SplashScreenView extends FrameLayout { /** * Set the background color for the icon. */ - public Builder setIconBackground(int color) { - mIconBackground = color; + public Builder setIconBackground(Drawable iconBackground) { + mIconBackground = iconBackground; return this; } @@ -245,7 +250,6 @@ public final class SplashScreenView extends FrameLayout { final SplashScreenView view = (SplashScreenView) layoutInflater.inflate(R.layout.splash_screen_view, null, false); view.mInitBackgroundColor = mBackgroundColor; - view.mInitIconBackgroundColor = mIconBackground; if (mOverlayDrawable != null) { view.setBackground(mOverlayDrawable); } else { @@ -263,25 +267,29 @@ public final class SplashScreenView extends FrameLayout { mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0); view.mIconAnimationStart = mIconAnimationStart; view.mIconAnimationDuration = mIconAnimationDuration; - } else { - view.mIconView = view.findViewById(R.id.splashscreen_icon_view); - if (mIconSize != 0) { - final ViewGroup.LayoutParams params = view.mIconView.getLayoutParams(); - params.width = mIconSize; - params.height = mIconSize; - view.mIconView.setLayoutParams(params); - if (mIconDrawable != null) { - view.mIconView.setBackground(mIconDrawable); - } + } else if (mIconSize != 0) { + ImageView imageView = view.findViewById(R.id.splashscreen_icon_view); + assert imageView != null; + + final ViewGroup.LayoutParams params = imageView.getLayoutParams(); + params.width = mIconSize; + params.height = mIconSize; + imageView.setLayoutParams(params); + if (mIconDrawable != null) { + imageView.setImageDrawable(mIconDrawable); } + if (mIconBackground != null) { + imageView.setBackground(mIconBackground); + } + view.mIconView = imageView; } if (mOverlayDrawable != null || mIconDrawable == null) { view.setNotCopyable(); } - if (mParceledIconBitmap != null) { - view.mParceledIconBitmap = mParceledIconBitmap; - } + view.mParceledIconBackgroundBitmap = mParceledIconBackgroundBitmap; + view.mParceledIconBitmap = mParceledIconBitmap; + // branding image if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) { final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams(); @@ -310,6 +318,7 @@ public final class SplashScreenView extends FrameLayout { private SurfaceView createSurfaceView(@NonNull SplashScreenView view) { final SurfaceView surfaceView = new SurfaceView(view.getContext()); surfaceView.setPadding(0, 0, 0, 0); + surfaceView.setBackground(mIconBackground); if (mSurfacePackage == null) { if (DEBUG) { Log.d(TAG, @@ -475,7 +484,11 @@ public final class SplashScreenView extends FrameLayout { } setVisibility(GONE); if (mParceledIconBitmap != null) { - mIconView.setBackground(null); + if (mIconView instanceof ImageView) { + ((ImageView) mIconView).setImageDrawable(null); + } else if (mIconView != null) { + mIconView.setBackground(null); + } mParceledIconBitmap.recycle(); mParceledIconBitmap = null; } @@ -484,6 +497,13 @@ public final class SplashScreenView extends FrameLayout { mParceledBrandingBitmap.recycle(); mParceledBrandingBitmap = null; } + if (mParceledIconBackgroundBitmap != null) { + if (mIconView != null) { + mIconView.setBackground(null); + } + mParceledIconBackgroundBitmap.recycle(); + mParceledIconBackgroundBitmap = null; + } if (mWindow != null) { final DecorView decorView = (DecorView) mWindow.peekDecorView(); if (DEBUG) { @@ -600,15 +620,6 @@ public final class SplashScreenView extends FrameLayout { } /** - * Get the icon background color - * @hide - */ - @TestApi - public @ColorInt int getIconBackgroundColor() { - return mInitIconBackgroundColor; - } - - /** * Get the initial background color of this view. * @hide */ @@ -637,7 +648,7 @@ public final class SplashScreenView extends FrameLayout { public static class SplashScreenViewParcelable implements Parcelable { private int mIconSize; private int mBackgroundColor; - private int mIconBackground; + private Bitmap mIconBackground; private Bitmap mIconBitmap = null; private int mBrandingWidth; @@ -653,11 +664,11 @@ public final class SplashScreenView extends FrameLayout { public SplashScreenViewParcelable(SplashScreenView view) { mIconSize = view.mIconView.getWidth(); mBackgroundColor = view.getInitBackgroundColor(); - mIconBackground = view.getIconBackgroundColor(); + mIconBackground = copyDrawable(view.getIconView().getBackground()); mSurfacePackage = view.mSurfacePackageCopy; if (mSurfacePackage == null) { // We only need to copy the drawable if we are not using a SurfaceView - mIconBitmap = copyDrawable(view.getIconView().getBackground()); + mIconBitmap = copyDrawable(((ImageView) view.getIconView()).getDrawable()); } mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground()); @@ -703,7 +714,7 @@ public final class SplashScreenView extends FrameLayout { mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR); mIconAnimationStartMillis = source.readLong(); mIconAnimationDurationMillis = source.readLong(); - mIconBackground = source.readInt(); + mIconBackground = source.readTypedObject(Bitmap.CREATOR); mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR); mClientCallback = source.readTypedObject(RemoteCallback.CREATOR); } @@ -723,7 +734,7 @@ public final class SplashScreenView extends FrameLayout { dest.writeTypedObject(mBrandingBitmap, flags); dest.writeLong(mIconAnimationStartMillis); dest.writeLong(mIconAnimationDurationMillis); - dest.writeInt(mIconBackground); + dest.writeTypedObject(mIconBackground, flags); dest.writeTypedObject(mSurfacePackage, flags); dest.writeTypedObject(mClientCallback, flags); } @@ -760,10 +771,6 @@ public final class SplashScreenView extends FrameLayout { return mBackgroundColor; } - int getIconBackground() { - return mIconBackground; - } - /** * Sets the {@link RemoteCallback} that will be called by the client to notify the shell * of the removal of the {@link SplashScreenView}. diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java index 55a2052f9242..c9a9e51dceed 100644 --- a/core/java/com/android/internal/display/BrightnessSynchronizer.java +++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java @@ -16,11 +16,9 @@ package com.android.internal.display; -import android.annotation.NonNull; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; -import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.net.Uri; @@ -63,10 +61,10 @@ public class BrightnessSynchronizer { updateBrightnessFloatFromInt(msg.arg1); break; case MSG_UPDATE_INT: - updateBrightnessIntFromFloat((BrightnessInfo) msg.obj); + updateBrightnessIntFromFloat(Float.intBitsToFloat(msg.arg1)); break; case MSG_UPDATE_BOTH: - updateBoth((BrightnessInfo) msg.obj, Float.intBitsToFloat(msg.arg1)); + updateBoth(Float.intBitsToFloat(msg.arg1)); break; default: super.handleMessage(msg); @@ -97,11 +95,11 @@ public class BrightnessSynchronizer { brightnessSyncObserver = new BrightnessSyncObserver(); brightnessSyncObserver.startObserving(); - final BrightnessInfo brightnessInfo = getBrightnessInfo(); + final float currentFloatBrightness = getScreenBrightnessFloat(); final int currentIntBrightness = getScreenBrightnessInt(mContext); - if (brightnessInfo != null && !Float.isNaN(brightnessInfo.brightness)) { - updateBrightnessIntFromFloat(brightnessInfo); + if (!Float.isNaN(currentFloatBrightness)) { + updateBrightnessIntFromFloat(currentFloatBrightness); } else if (currentIntBrightness != -1) { updateBrightnessFloatFromInt(currentIntBrightness); } else { @@ -114,23 +112,15 @@ public class BrightnessSynchronizer { /** * Converts between the int brightness system and the float brightness system. - * - * @param brightnessInt The int brightness value to convert. */ public static float brightnessIntToFloat(int brightnessInt) { - return brightnessIntToFloat(brightnessInt, null); - } - - private static float brightnessIntToFloat(int brightnessInt, BrightnessInfo info) { if (brightnessInt == PowerManager.BRIGHTNESS_OFF) { return PowerManager.BRIGHTNESS_OFF_FLOAT; } else if (brightnessInt == PowerManager.BRIGHTNESS_INVALID) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } else { - final float minFloat = info != null - ? info.brightnessMinimum : PowerManager.BRIGHTNESS_MIN; - final float maxFloat = info != null - ? info.brightnessMaximum : PowerManager.BRIGHTNESS_MAX; + final float minFloat = PowerManager.BRIGHTNESS_MIN; + final float maxFloat = PowerManager.BRIGHTNESS_MAX; final float minInt = PowerManager.BRIGHTNESS_OFF + 1; final float maxInt = PowerManager.BRIGHTNESS_ON; return MathUtils.constrainedMap(minFloat, maxFloat, minInt, maxInt, brightnessInt); @@ -138,28 +128,29 @@ public class BrightnessSynchronizer { } /** + * Converts between the float brightness system and the int brightness system. + */ + public static int brightnessFloatToInt(float brightnessFloat) { + return Math.round(brightnessFloatToIntRange(brightnessFloat)); + } + + /** * Translates specified value from the float brightness system to the int brightness system, * given the min/max of each range. Accounts for special values such as OFF and invalid values. * Value returned as a float primitive (to preserve precision), but is a value within the * int-system range. - * - * @param brightnessFloat The float brightness value to convert. - * @param info Brightness information to use in the conversion. */ - public static int brightnessFloatToInt(float brightnessFloat, BrightnessInfo info) { + public static float brightnessFloatToIntRange(float brightnessFloat) { if (floatEquals(brightnessFloat, PowerManager.BRIGHTNESS_OFF_FLOAT)) { return PowerManager.BRIGHTNESS_OFF; } else if (Float.isNaN(brightnessFloat)) { return PowerManager.BRIGHTNESS_INVALID; } else { - final float minFloat = info != null - ? info.brightnessMinimum : PowerManager.BRIGHTNESS_MIN; - final float maxFloat = info != null - ? info.brightnessMaximum : PowerManager.BRIGHTNESS_MAX; + final float minFloat = PowerManager.BRIGHTNESS_MIN; + final float maxFloat = PowerManager.BRIGHTNESS_MAX; final float minInt = PowerManager.BRIGHTNESS_OFF + 1; final float maxInt = PowerManager.BRIGHTNESS_ON; - return Math.round(MathUtils.constrainedMap(minInt, maxInt, minFloat, maxFloat, - brightnessFloat)); + return MathUtils.constrainedMap(minInt, maxInt, minFloat, maxFloat, brightnessFloat); } } @@ -194,37 +185,35 @@ public class BrightnessSynchronizer { * @param value Brightness value as int to store in the float setting. */ private void updateBrightnessFloatFromInt(int value) { - final BrightnessInfo info = getBrightnessInfo(); - if (brightnessFloatToInt(mPreferredSettingValue, info) == value) { + if (brightnessFloatToInt(mPreferredSettingValue) == value) { return; } - mPreferredSettingValue = brightnessIntToFloat(value, info); + mPreferredSettingValue = brightnessIntToFloat(value); final int newBrightnessAsIntBits = Float.floatToIntBits(mPreferredSettingValue); mHandler.removeMessages(MSG_UPDATE_BOTH); mHandler.obtainMessage(MSG_UPDATE_BOTH, newBrightnessAsIntBits, 0).sendToTarget(); } /** - * Updates the settings from the specified {@link BrightnessInfo}. This is called whenever the - * float brightness changed from DisplayManager. mPreferredSettingValue holds the most recently - * updated brightness value as a float that we would like the display to be set to. + * Updates the settings based on a passed in float value. This is called whenever the float + * setting changes. mPreferredSettingValue holds the most recently updated brightness value + * as a float that we would like the display to be set to. * * We then schedule an update to both the int and float settings, but, remove all the other * messages to update all, to prevent us getting stuck in a loop. * - * @param brightnessInfo Current brightness information + * @param value Brightness setting as float to store in int setting. */ - private void updateBrightnessIntFromFloat(@NonNull BrightnessInfo brightnessInfo) { - final float value = brightnessInfo.brightness; + private void updateBrightnessIntFromFloat(float value) { if (floatEquals(mPreferredSettingValue, value)) { return; } mPreferredSettingValue = value; + final int newBrightnessAsIntBits = Float.floatToIntBits(mPreferredSettingValue); mHandler.removeMessages(MSG_UPDATE_BOTH); - mHandler.obtainMessage(MSG_UPDATE_BOTH, Float.floatToIntBits(value), 0, brightnessInfo) - .sendToTarget(); + mHandler.obtainMessage(MSG_UPDATE_BOTH, newBrightnessAsIntBits, 0).sendToTarget(); } @@ -233,24 +222,16 @@ public class BrightnessSynchronizer { * mDisplayManager.setBrightness automatically checks for changes * Settings.System.putIntForUser needs to be checked, to prevent an extra callback to this class * - * @param brightnessInfo Brightness information, takes precedent over newBrightnessFloat * @param newBrightnessFloat Brightness setting as float to store in both settings */ - private void updateBoth(BrightnessInfo brightnessInfo, float newBrightnessFloat) { - int newBrightnessInt = brightnessFloatToInt(newBrightnessFloat, brightnessInfo); + private void updateBoth(float newBrightnessFloat) { + int newBrightnessInt = brightnessFloatToInt(newBrightnessFloat); mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat); if (getScreenBrightnessInt(mContext) != newBrightnessInt) { Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, newBrightnessInt, UserHandle.USER_CURRENT); } - } - private BrightnessInfo getBrightnessInfo() { - final Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); - if (display != null) { - return display.getBrightnessInfo(); - } - return null; } /** @@ -282,15 +263,10 @@ public class BrightnessSynchronizer { @Override public void onDisplayChanged(int displayId) { - if (displayId != Display.DEFAULT_DISPLAY) { - return; - } - - final BrightnessInfo info = getBrightnessInfo(); - if (info != null) { - mHandler.removeMessages(MSG_UPDATE_INT); - mHandler.obtainMessage(MSG_UPDATE_INT, info).sendToTarget(); - } + float currentFloat = getScreenBrightnessFloat(); + int toSend = Float.floatToIntBits(currentFloat); + mHandler.removeMessages(MSG_UPDATE_INT); + mHandler.obtainMessage(MSG_UPDATE_INT, toSend, 0).sendToTarget(); } }; diff --git a/core/java/com/android/internal/infra/AndroidFuture.java b/core/java/com/android/internal/infra/AndroidFuture.java index db5d06635e94..84391c169941 100644 --- a/core/java/com/android/internal/infra/AndroidFuture.java +++ b/core/java/com/android/internal/infra/AndroidFuture.java @@ -24,6 +24,7 @@ import android.os.Looper; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; +import android.util.EventLog; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -601,9 +602,14 @@ public class AndroidFuture<T> extends CompletableFuture<T> implements Parcelable String messageWithStackTrace = message + '\n' + stackTrace; Throwable throwable; try { - Class<?> clazz = Class.forName(className); - Constructor<?> constructor = clazz.getConstructor(String.class); - throwable = (Throwable) constructor.newInstance(messageWithStackTrace); + Class<?> clazz = Class.forName(className, true, Parcelable.class.getClassLoader()); + if (Throwable.class.isAssignableFrom(clazz)) { + Constructor<?> constructor = clazz.getConstructor(String.class); + throwable = (Throwable) constructor.newInstance(messageWithStackTrace); + } else { + android.util.EventLog.writeEvent(0x534e4554, "186530450", -1, ""); + throwable = new RuntimeException(className + ": " + messageWithStackTrace); + } } catch (Throwable t) { throwable = new RuntimeException(className + ": " + messageWithStackTrace); throwable.addSuppressed(t); diff --git a/core/java/com/android/internal/os/ProcLocksReader.java b/core/java/com/android/internal/os/ProcLocksReader.java new file mode 100644 index 000000000000..bd3115fc5d4c --- /dev/null +++ b/core/java/com/android/internal/os/ProcLocksReader.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2021 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.internal.os; + +import com.android.internal.util.ProcFileReader; + +import libcore.io.IoUtils; + +import java.io.FileInputStream; +import java.io.IOException; + +/** + * Reads and parses {@code locks} files in the {@code proc} filesystem. + * A typical example of /proc/locks + * + * 1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335 + * 2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF + * 2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF + * 2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF + * 3: POSIX ADVISORY READ 3888 fd:09:13992 128 128 + * 4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335 + */ +public class ProcLocksReader { + private final String mPath; + + public ProcLocksReader() { + mPath = "/proc/locks"; + } + + public ProcLocksReader(String path) { + mPath = path; + } + + /** + * Checks if a process corresponding to a specific pid owns any file locks. + * @param pid The process ID for which we want to know the existence of file locks. + * @return true If the process holds any file locks, false otherwise. + * @throws IOException if /proc/locks can't be accessed. + */ + public boolean hasFileLocks(int pid) throws Exception { + ProcFileReader reader = null; + long last = -1; + long id; // ordinal position of the lock in the list + int owner; // the PID of the process that owns the lock + + try { + reader = new ProcFileReader(new FileInputStream(mPath)); + + while (reader.hasMoreData()) { + id = reader.nextLong(true); // lock id + if (id == last) { + reader.finishLine(); // blocked lock + continue; + } + + reader.nextIgnored(); // lock type: POSIX? + reader.nextIgnored(); // lock type: MANDATORY? + reader.nextIgnored(); // lock type: RW? + + owner = reader.nextInt(); // pid + if (owner == pid) { + return true; + } + reader.finishLine(); + last = id; + } + } catch (IOException e) { + // TODO: let ProcFileReader log the failed line + throw new Exception("Exception parsing /proc/locks"); + } finally { + IoUtils.closeQuietly(reader); + } + return false; + } +} diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java index ead58c7de611..0dd8ad89df61 100644 --- a/core/java/com/android/internal/util/ProcFileReader.java +++ b/core/java/com/android/internal/util/ProcFileReader.java @@ -28,8 +28,8 @@ import java.nio.charset.StandardCharsets; * requires each line boundary to be explicitly acknowledged using * {@link #finishLine()}. Assumes {@link StandardCharsets#US_ASCII} encoding. * <p> - * Currently doesn't support formats based on {@code \0}, tabs, or repeated - * delimiters. + * Currently doesn't support formats based on {@code \0}, tabs. + * Consecutive spaces are treated as a single delimiter. */ public class ProcFileReader implements Closeable { private final InputStream mStream; @@ -75,6 +75,11 @@ public class ProcFileReader implements Closeable { private void consumeBuf(int count) throws IOException { // TODO: consider moving to read pointer, but for now traceview says // these copies aren't a bottleneck. + + // skip all consecutive delimiters. + while (count < mTail && mBuffer[count] == ' ') { + count++; + } System.arraycopy(mBuffer, count, mBuffer, 0, mTail - count); mTail -= count; if (mTail == 0) { @@ -159,11 +164,18 @@ public class ProcFileReader implements Closeable { * Parse and return next token as base-10 encoded {@code long}. */ public long nextLong() throws IOException { + return nextLong(false); + } + + /** + * Parse and return next token as base-10 encoded {@code long}. + */ + public long nextLong(boolean stopAtInvalid) throws IOException { final int tokenIndex = nextTokenIndex(); if (tokenIndex == -1) { throw new ProtocolException("Missing required long"); } else { - return parseAndConsumeLong(tokenIndex); + return parseAndConsumeLong(tokenIndex, stopAtInvalid); } } @@ -176,7 +188,7 @@ public class ProcFileReader implements Closeable { if (tokenIndex == -1) { return def; } else { - return parseAndConsumeLong(tokenIndex); + return parseAndConsumeLong(tokenIndex, false); } } @@ -186,7 +198,10 @@ public class ProcFileReader implements Closeable { return s; } - private long parseAndConsumeLong(int tokenIndex) throws IOException { + /** + * If stopAtInvalid is true, don't throw IOException but return whatever parsed so far. + */ + private long parseAndConsumeLong(int tokenIndex, boolean stopAtInvalid) throws IOException { final boolean negative = mBuffer[0] == '-'; // TODO: refactor into something like IntegralToString @@ -194,7 +209,11 @@ public class ProcFileReader implements Closeable { for (int i = negative ? 1 : 0; i < tokenIndex; i++) { final int digit = mBuffer[i] - '0'; if (digit < 0 || digit > 9) { - throw invalidLong(tokenIndex); + if (stopAtInvalid) { + break; + } else { + throw invalidLong(tokenIndex); + } } // always parse as negative number and apply sign later; this @@ -226,6 +245,18 @@ public class ProcFileReader implements Closeable { return (int) value; } + /** + * Bypass the next token. + */ + public void nextIgnored() throws IOException { + final int tokenIndex = nextTokenIndex(); + if (tokenIndex == -1) { + throw new ProtocolException("Missing required token"); + } else { + consumeBuf(tokenIndex + 1); + } + } + @Override public void close() throws IOException { mStream.close(); diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index b46b5a23e3fb..d4ae6d769cf7 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -105,9 +105,11 @@ static void nativeSetNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong } static void nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width, - jlong height, jint format) { + jlong height, jint format, jlong transactionPtr) { sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr); - queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format); + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr); + queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format, + transaction); } static void nativeFlushShadowQueue(JNIEnv* env, jclass clazz, jlong ptr) { @@ -144,7 +146,7 @@ static const JNINativeMethod gMethods[] = { {"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface}, {"nativeDestroy", "(J)V", (void*)nativeDestroy}, {"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction}, - {"nativeUpdate", "(JJJJI)V", (void*)nativeUpdate}, + {"nativeUpdate", "(JJJJIJ)V", (void*)nativeUpdate}, {"nativeFlushShadowQueue", "(J)V", (void*)nativeFlushShadowQueue}, {"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction}, {"nativeSetTransactionCompleteCallback", diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4dec0ffccb5e..95c24ad4a115 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -616,7 +616,11 @@ <protected-broadcast android:name="com.android.server.fingerprint.ACTION_LOCKOUT_RESET" /> <protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" /> + <protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" /> + <protected-broadcast android:name="android.server.notification.action.ENABLE_NAS" /> + <protected-broadcast android:name="android.server.notification.action.DISABLE_NAS" /> + <protected-broadcast android:name="android.server.notification.action.LEARNMORE_NAS" /> <protected-broadcast android:name="com.android.internal.location.ALARM_WAKEUP" /> <protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" /> @@ -3503,7 +3507,7 @@ use by third party apps. @hide --> <permission android:name="android.permission.UPDATE_APP_OPS_STATS" - android:protectionLevel="signature|privileged|installer" /> + android:protectionLevel="signature|privileged|installer|role" /> <!-- @SystemApi Allows an application to update the user app op restrictions. Not for use by third party apps. diff --git a/core/res/res/layout/splash_screen_view.xml b/core/res/res/layout/splash_screen_view.xml index 0b7b49cdea83..aa050f3a364d 100644 --- a/core/res/res/layout/splash_screen_view.xml +++ b/core/res/res/layout/splash_screen_view.xml @@ -21,12 +21,11 @@ android:padding="0dp" android:orientation="vertical"> - <View android:id="@+id/splashscreen_icon_view" + <ImageView android:id="@+id/splashscreen_icon_view" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="center" android:padding="0dp" - android:background="@null" android:contentDescription="@string/splash_screen_view_icon_description"/> <View android:id="@+id/splashscreen_branding_view" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index cf2f677dfb35..0310b181398d 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -2079,7 +2079,7 @@ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع الاتصال"</string> <string name="call_notification_incoming_text" msgid="6143109825406638201">"مكالمة واردة"</string> <string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string> - <string name="call_notification_screening_text" msgid="8396931408268940208">"رصد مكالمة واردة"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"يتم فحص المكالمة الواردة"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="zero">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item> <item quantity="two">تم اختيار عنصرين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 542387f2047e..199e82f9d170 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -984,7 +984,7 @@ <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nMöchtest du diese Seite wirklich verlassen?"</string> <string name="save_password_label" msgid="9161712335355510035">"Bestätigen"</string> <string name="double_tap_toast" msgid="7065519579174882778">"Tipp: Zum Vergrößern und Verkleinern doppeltippen"</string> - <string name="autofill_this_form" msgid="3187132440451621492">"AutoFill"</string> + <string name="autofill_this_form" msgid="3187132440451621492">"Automatisches Ausfüllen"</string> <string name="setup_autofill" msgid="5431369130866618567">"Autom.Ausfüll.konf."</string> <string name="autofill_window_title" msgid="4379134104008111961">"Mit <xliff:g id="SERVICENAME">%1$s</xliff:g> automatisch ausfüllen"</string> <string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 9a07025ad760..9a29addc10b0 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -271,7 +271,7 @@ <string name="global_action_settings" msgid="4671878836947494217">"Ajustes"</string> <string name="global_action_assist" msgid="2517047220311505805">"Asistencia"</string> <string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string> - <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo seguro"</string> + <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo de seguridad"</string> <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"> 999"</string> <string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string> <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Teclado virtual"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 12f8cd427d7f..6da40726d123 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1951,7 +1951,7 @@ <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> <string name="call_notification_answer_action" msgid="5999246836247132937">"जवाफ दिनुहोस्"</string> <string name="call_notification_answer_video_action" msgid="2086030940195382249">"भिडियो"</string> - <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार गर्नुहोस्"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"काट्नुहोस्"</string> <string name="call_notification_hang_up_action" msgid="9130720590159188131">"फोन राख्नुहोस्"</string> <string name="call_notification_incoming_text" msgid="6143109825406638201">"आगमन कल"</string> <string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string> diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml index 816ddd41ccd3..2e4578c39430 100644 --- a/core/res/res/values-night/colors.xml +++ b/core/res/res/values-night/colors.xml @@ -29,5 +29,8 @@ <color name="resolver_empty_state_text">#FFFFFF</color> <color name="resolver_empty_state_icon">#FFFFFF</color> + <color name="call_notification_decline_color">#E66A5E</color> + <color name="call_notification_answer_color">#5DBA80</color> + <color name="personal_apps_suspension_notification_color">#8AB4F8</color> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 89a77495eefd..893aedae146d 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -87,7 +87,7 @@ <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ప్రాధాన్య నెట్వర్క్ను మార్చుకోవడానికి ప్రయత్నించండి. మార్చడానికి నొక్కండి."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"అత్యవసర కాలింగ్ అందుబాటులో లేదు"</string> <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fiతో అత్యవసర కాల్లు చేయలేరు"</string> - <string name="notification_channel_network_alert" msgid="4788053066033851841">"హెచ్చరికలు"</string> + <string name="notification_channel_network_alert" msgid="4788053066033851841">"అలర్ట్లు"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"కాల్ ఫార్వార్డింగ్"</string> <string name="notification_channel_emergency_callback" msgid="54074839059123159">"అత్యవసర కాల్బ్యాక్ మోడ్"</string> <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"మొబైల్ డేటా స్థితి"</string> @@ -287,7 +287,7 @@ <string name="notification_channel_network_available" msgid="6083697929214165169">"నెట్వర్క్ అందుబాటులో ఉంది"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN స్థితి"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"మీ IT నిర్వాహకుల నుండి వచ్చే హెచ్చరికలు"</string> - <string name="notification_channel_alerts" msgid="5070241039583668427">"హెచ్చరికలు"</string> + <string name="notification_channel_alerts" msgid="5070241039583668427">"అలర్ట్లు"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"రిటైల్ డెమో"</string> <string name="notification_channel_usb" msgid="1528280969406244896">"USB కనెక్షన్"</string> <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"యాప్ అమలవుతోంది"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 3f9cee11da36..2936a080723b 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1949,7 +1949,7 @@ <string name="maximize_button_text" msgid="4258922519914732645">"بڑا کریں"</string> <string name="close_button_text" msgid="10603510034455258">"بند کریں"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> - <string name="call_notification_answer_action" msgid="5999246836247132937">"جواب"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"جواب دیں"</string> <string name="call_notification_answer_video_action" msgid="2086030940195382249">"ویڈیو"</string> <string name="call_notification_decline_action" msgid="3700345945214000726">"مسترد کریں"</string> <string name="call_notification_hang_up_action" msgid="9130720590159188131">"منقطع کر دیں"</string> diff --git a/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java b/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java new file mode 100644 index 000000000000..d800c2c3c66e --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 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.internal.os; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.Context; +import android.os.FileUtils; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; +import java.nio.file.Files; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ProcLocksReaderTest { + private File mProcDirectory; + + @Before + public void setUp() { + Context context = InstrumentationRegistry.getContext(); + mProcDirectory = context.getDir("proc", Context.MODE_PRIVATE); + } + + @After + public void tearDown() throws Exception { + FileUtils.deleteContents(mProcDirectory); + } + + @Test + public void testRunSimpleLocks() throws Exception { + String simpleLocks = + "1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335\n" + + "2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF\n"; + assertFalse(runHasFileLocks(simpleLocks, 18402)); + assertFalse(runHasFileLocks(simpleLocks, 18404)); + assertTrue(runHasFileLocks(simpleLocks, 18403)); + assertTrue(runHasFileLocks(simpleLocks, 18292)); + } + + @Test + public void testRunBlockedLocks() throws Exception { + String blockedLocks = + "1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335\n" + + "2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF\n" + + "2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF\n" + + "2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF\n" + + "3: POSIX ADVISORY READ 3888 fd:09:13992 128 128\n" + + "4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335\n"; + assertFalse(runHasFileLocks(blockedLocks, 18402)); + assertFalse(runHasFileLocks(blockedLocks, 18404)); + assertTrue(runHasFileLocks(blockedLocks, 18403)); + assertTrue(runHasFileLocks(blockedLocks, 18292)); + + assertFalse(runHasFileLocks(blockedLocks, 18291)); + assertFalse(runHasFileLocks(blockedLocks, 18293)); + assertTrue(runHasFileLocks(blockedLocks, 3888)); + } + + private boolean runHasFileLocks(String fileContents, int pid) throws Exception { + File tempFile = File.createTempFile("locks", null, mProcDirectory); + Files.write(tempFile.toPath(), fileContents.getBytes()); + boolean result = new ProcLocksReader(tempFile.toString()).hasFileLocks(pid); + Files.delete(tempFile.toPath()); + return result; + } +} diff --git a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java index b6da1954ba79..0532628ba16d 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java @@ -166,6 +166,46 @@ public class ProcFileReaderTest extends AndroidTestCase { assertEquals(-1L, reader.nextOptionalLong(-1L)); } + public void testInvalidLongs() throws Exception { + final ProcFileReader reader = buildReader("12: 34\n56 78@#\n"); + + assertEquals(12L, reader.nextLong(true)); + assertEquals(34L, reader.nextLong(true)); + reader.finishLine(); + assertTrue(reader.hasMoreData()); + + assertEquals(56L, reader.nextLong(true)); + assertEquals(78L, reader.nextLong(true)); + reader.finishLine(); + assertFalse(reader.hasMoreData()); + } + + public void testConsecutiveDelimiters() throws Exception { + final ProcFileReader reader = buildReader("1 2 3 4 5\n"); + + assertEquals(1L, reader.nextLong()); + assertEquals(2L, reader.nextLong()); + assertEquals(3L, reader.nextLong()); + assertEquals(4L, reader.nextLong()); + assertEquals(5L, reader.nextLong()); + reader.finishLine(); + assertFalse(reader.hasMoreData()); + } + + public void testIgnore() throws Exception { + final ProcFileReader reader = buildReader("a b c\n"); + + assertEquals("a", reader.nextString()); + assertTrue(reader.hasMoreData()); + + reader.nextIgnored(); + assertTrue(reader.hasMoreData()); + + assertEquals("c", reader.nextString()); + reader.finishLine(); + assertFalse(reader.hasMoreData()); + } + private static ProcFileReader buildReader(String string) throws IOException { return buildReader(string, 2048); } diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 6c1c2ee1ee57..36215ecc1403 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -33,7 +33,7 @@ public final class BLASTBufferQueue { private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle); private static native void nativeSetNextTransaction(long ptr, long transactionPtr); private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height, - int format); + int format, long transactionPtr); private static native void nativeFlushShadowQueue(long ptr); private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr, long frameNumber); @@ -92,9 +92,15 @@ public final class BLASTBufferQueue { * @param width The new width for the buffer. * @param height The new height for the buffer. * @param format The new format for the buffer. + * @param t Adds destination frame changes to the passed in transaction. */ + public void update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format, + SurfaceControl.Transaction t) { + nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format, t.mNativeObject); + } + public void update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format) { - nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format); + nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format, 0); } /** diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java index 74fb618f8fd7..492520910afd 100644 --- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java +++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java @@ -53,6 +53,7 @@ public final class RippleAnimationSession { private long mStartTime; private boolean mForceSoftware; private Animator mLoopAnimation; + private Animator mCurrentAnimation; RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties, boolean forceSoftware) { @@ -74,6 +75,12 @@ public final class RippleAnimationSession { return this; } + void end() { + if (mCurrentAnimation != null) { + mCurrentAnimation.end(); + } + } + @NonNull RippleAnimationSession exit(Canvas canvas) { if (isHwAccelerated(canvas)) exitHardware((RecordingCanvas) canvas); else exitSoftware(); @@ -114,10 +121,12 @@ public final class RippleAnimationSession { if (mLoopAnimation != null) mLoopAnimation.cancel(); Consumer<RippleAnimationSession> onEnd = mOnSessionEnd; if (onEnd != null) onEnd.accept(RippleAnimationSession.this); + if (mCurrentAnimation == expand) mCurrentAnimation = null; } }); expand.setInterpolator(LINEAR_INTERPOLATOR); expand.start(); + mCurrentAnimation = expand; } private long computeDelay() { @@ -147,6 +156,7 @@ public final class RippleAnimationSession { if (mLoopAnimation != null) mLoopAnimation.cancel(); Consumer<RippleAnimationSession> onEnd = mOnSessionEnd; if (onEnd != null) onEnd.accept(RippleAnimationSession.this); + if (mCurrentAnimation == exit) mCurrentAnimation = null; } }); exit.setTarget(canvas); @@ -155,6 +165,7 @@ public final class RippleAnimationSession { long delay = computeDelay(); exit.setStartDelay(delay); exit.start(); + mCurrentAnimation = exit; } private void enterHardware(RecordingCanvas canvas) { @@ -167,6 +178,7 @@ public final class RippleAnimationSession { mStartTime + MAX_NOISE_PHASE); loop.setTarget(canvas); startAnimation(expand, loop); + mCurrentAnimation = expand; } private void startAnimation(Animator expand, Animator loop) { @@ -200,6 +212,7 @@ public final class RippleAnimationSession { mProperties.getShader().setNoisePhase((float) loop.getAnimatedValue()); }); startAnimation(expand, loop); + mCurrentAnimation = expand; } void setRadius(float radius) { diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index b994ad20320b..d3cff5cb81ff 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -278,6 +278,15 @@ public class RippleDrawable extends LayerDrawable { } cancelExitingRipples(); + endPatternedAnimations(); + } + + private void endPatternedAnimations() { + for (int i = 0; i < mRunningAnimations.size(); i++) { + RippleAnimationSession session = mRunningAnimations.get(i); + session.end(); + } + mRunningAnimations.clear(); } private void cancelExitingRipples() { @@ -291,7 +300,6 @@ public class RippleDrawable extends LayerDrawable { Arrays.fill(ripples, 0, count, null); } mExitingRipplesCount = 0; - mExitingAnimation = true; // Always draw an additional "clean" frame after canceling animations. invalidateSelf(false); } @@ -714,7 +722,7 @@ public class RippleDrawable extends LayerDrawable { } cancelExitingRipples(); - exitPatternedAnimation(); + endPatternedAnimations(); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java index 24e511143cff..8969cc8a7da9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java @@ -46,7 +46,7 @@ public interface OneHandedAnimationCallback { /** * Called when OneHanded animator is updating position */ - default void onAnimationUpdate(float xPos, float yPos) { + default void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) { } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java index bfb2cc6a8fc5..4b7832845a1d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java @@ -182,10 +182,10 @@ public class OneHandedAnimationController { @Override public void onAnimationUpdate(ValueAnimator animation) { final SurfaceControl.Transaction tx = newSurfaceControlTransaction(); - applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction()); mOneHandedAnimationCallbacks.forEach( - (callback) -> callback.onAnimationUpdate(0f, mCurrentValue) + (callback) -> callback.onAnimationUpdate(tx, 0f, mCurrentValue) ); + applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction()); } void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java index 3ccb9e7570d5..97461e607e66 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java @@ -16,12 +16,14 @@ package com.android.wm.shell.onehanded; +import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Rect; import android.view.SurfaceControl; import android.view.SurfaceSession; +import android.view.animation.LinearInterpolator; import android.window.DisplayAreaAppearedInfo; import android.window.DisplayAreaInfo; import android.window.DisplayAreaOrganizer; @@ -29,8 +31,8 @@ import android.window.DisplayAreaOrganizer; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.appcompat.view.ContextThemeWrapper; -import com.android.internal.annotations.GuardedBy; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayLayout; @@ -44,194 +46,212 @@ import java.util.concurrent.Executor; * the screen has entered one handed mode. */ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer - implements OneHandedTransitionCallback { + implements OneHandedAnimationCallback { private static final String TAG = "OneHandedBackgroundPanelOrganizer"; private static final int THEME_COLOR_OFFSET = 10; + private static final int ALPHA_ANIMATION_DURATION = 200; private final Context mContext; - private final Object mLock = new Object(); private final SurfaceSession mSurfaceSession = new SurfaceSession(); - private final Executor mMainExecutor; private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory - mSurfaceControlTransactionFactory; + mTransactionFactory; - private float[] mDefaultColor; + private ValueAnimator mAlphaAnimator; + + private float mTranslationFraction; + private float[] mThemeColor; /** * The background to distinguish the boundary of translated windows and empty region when * one handed mode triggered. */ private Rect mBkgBounds; - @VisibleForTesting - @GuardedBy("mLock") - boolean mIsShowing; + private Rect mStableInsets; + @Nullable - @GuardedBy("mLock") - private SurfaceControl mBackgroundSurface; + @VisibleForTesting + SurfaceControl mBackgroundSurface; @Nullable - @GuardedBy("mLock") private SurfaceControl mParentLeash; - private final OneHandedAnimationCallback mOneHandedAnimationCallback = - new OneHandedAnimationCallback() { - @Override - public void onOneHandedAnimationStart( - OneHandedAnimationController.OneHandedTransitionAnimator animator) { - mMainExecutor.execute(() -> showBackgroundPanelLayer()); - } - }; - - @Override - public void onStopFinished(Rect bounds) { - mMainExecutor.execute(() -> removeBackgroundPanelLayer()); - } - public OneHandedBackgroundPanelOrganizer(Context context, DisplayLayout displayLayout, - Executor executor) { + OneHandedSettingsUtil settingsUtil, Executor executor) { super(executor); mContext = context; - // Ensure the mBkgBounds is portrait, due to OHM only support on portrait - if (displayLayout.height() > displayLayout.width()) { - mBkgBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); - } else { - mBkgBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width()); - } + mTranslationFraction = settingsUtil.getTranslationFraction(context); + mTransactionFactory = SurfaceControl.Transaction::new; updateThemeColors(); - mMainExecutor = executor; - mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; } @Override public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo, @NonNull SurfaceControl leash) { - synchronized (mLock) { - if (mParentLeash == null) { - mParentLeash = leash; - } else { - throw new RuntimeException("There should be only one DisplayArea for " - + "the one-handed mode background panel"); - } - } - } - - OneHandedAnimationCallback getOneHandedAnimationCallback() { - return mOneHandedAnimationCallback; + mParentLeash = leash; } @Override public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) { - synchronized (mLock) { - final List<DisplayAreaAppearedInfo> displayAreaInfos; - displayAreaInfos = super.registerOrganizer(displayAreaFeature); - for (int i = 0; i < displayAreaInfos.size(); i++) { - final DisplayAreaAppearedInfo info = displayAreaInfos.get(i); - onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash()); - } - return displayAreaInfos; + final List<DisplayAreaAppearedInfo> displayAreaInfos; + displayAreaInfos = super.registerOrganizer(displayAreaFeature); + for (int i = 0; i < displayAreaInfos.size(); i++) { + final DisplayAreaAppearedInfo info = displayAreaInfos.get(i); + onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash()); } + return displayAreaInfos; } @Override public void unregisterOrganizer() { - synchronized (mLock) { - super.unregisterOrganizer(); - mParentLeash = null; - } + super.unregisterOrganizer(); + removeBackgroundPanelLayer(); + mParentLeash = null; + } + + @Override + public void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) { + final int yTopPos = (mStableInsets.top - mBkgBounds.height()) + Math.round(yPos); + tx.setPosition(mBackgroundSurface, 0, yTopPos); } @Nullable @VisibleForTesting - SurfaceControl getBackgroundSurface() { - synchronized (mLock) { - if (mParentLeash == null) { - return null; - } - - if (mBackgroundSurface == null) { - mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession) - .setParent(mParentLeash) - .setBufferSize(mBkgBounds.width(), mBkgBounds.height()) - .setColorLayer() - .setFormat(PixelFormat.RGB_888) - .setOpaque(true) - .setName("one-handed-background-panel") - .setCallsite("OneHandedBackgroundPanelOrganizer") - .build(); - } - return mBackgroundSurface; + boolean isRegistered() { + return mParentLeash != null; + } + + void createBackgroundSurface() { + mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession) + .setBufferSize(mBkgBounds.width(), mBkgBounds.height()) + .setColorLayer() + .setFormat(PixelFormat.RGB_888) + .setOpaque(true) + .setName("one-handed-background-panel") + .setCallsite("OneHandedBackgroundPanelOrganizer") + .build(); + + // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash. + mAlphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f); + mAlphaAnimator.setInterpolator(new LinearInterpolator()); + mAlphaAnimator.setDuration(ALPHA_ANIMATION_DURATION); + mAlphaAnimator.addUpdateListener( + animator -> detachBackgroundFromParent(animator)); + } + + void detachBackgroundFromParent(ValueAnimator animator) { + if (mBackgroundSurface == null || mParentLeash == null) { + return; + } + // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash. + final float currentValue = (float) animator.getAnimatedValue(); + final SurfaceControl.Transaction tx = mTransactionFactory.getTransaction(); + if (currentValue == 0.0f) { + tx.reparent(mBackgroundSurface, null).apply(); + } else { + tx.setAlpha(mBackgroundSurface, (float) animator.getAnimatedValue()).apply(); } } + /** + * Called when onDisplayAdded() or onDisplayRemoved() callback. + * + * @param displayLayout The latest {@link DisplayLayout} representing current displayId + */ + public void onDisplayChanged(DisplayLayout displayLayout) { + mStableInsets = displayLayout.stableInsets(); + // Ensure the mBkgBounds is portrait, due to OHM only support on portrait + if (displayLayout.height() > displayLayout.width()) { + mBkgBounds = new Rect(0, 0, displayLayout.width(), + Math.round(displayLayout.height() * mTranslationFraction) + mStableInsets.top); + } else { + mBkgBounds = new Rect(0, 0, displayLayout.height(), + Math.round(displayLayout.width() * mTranslationFraction) + mStableInsets.top); + } + } + + @VisibleForTesting + void onStart() { + if (mBackgroundSurface == null) { + createBackgroundSurface(); + } + showBackgroundPanelLayer(); + } + + /** + * Called when transition finished. + */ + public void onStopFinished() { + mAlphaAnimator.start(); + } + @VisibleForTesting void showBackgroundPanelLayer() { - synchronized (mLock) { - if (mIsShowing) { - return; - } - - if (getBackgroundSurface() == null) { - return; - } - - SurfaceControl.Transaction transaction = - mSurfaceControlTransactionFactory.getTransaction(); - transaction.setLayer(mBackgroundSurface, -1 /* at bottom-most layer */) - .setColor(mBackgroundSurface, mDefaultColor) - .show(mBackgroundSurface) - .apply(); - transaction.close(); - mIsShowing = true; + if (mParentLeash == null) { + return; + } + + if (mBackgroundSurface == null) { + createBackgroundSurface(); } + + // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash. + if (mAlphaAnimator.isRunning()) { + mAlphaAnimator.end(); + } + + mTransactionFactory.getTransaction() + .reparent(mBackgroundSurface, mParentLeash) + .setAlpha(mBackgroundSurface, 1.0f) + .setLayer(mBackgroundSurface, -1 /* at bottom-most layer */) + .setColor(mBackgroundSurface, mThemeColor) + .show(mBackgroundSurface) + .apply(); } @VisibleForTesting void removeBackgroundPanelLayer() { - synchronized (mLock) { - if (mBackgroundSurface == null) { - return; - } - - SurfaceControl.Transaction transaction = - mSurfaceControlTransactionFactory.getTransaction(); - transaction.remove(mBackgroundSurface).apply(); - transaction.close(); - mBackgroundSurface = null; - mIsShowing = false; + if (mBackgroundSurface == null) { + return; } + + mTransactionFactory.getTransaction() + .remove(mBackgroundSurface) + .apply(); + mBackgroundSurface = null; } /** * onConfigurationChanged events for updating tutorial text. */ public void onConfigurationChanged() { - synchronized (mLock) { - if (mBackgroundSurface == null) { - getBackgroundSurface(); - } else { - removeBackgroundPanelLayer(); - } - updateThemeColors(); - showBackgroundPanelLayer(); - } + updateThemeColors(); + showBackgroundPanelLayer(); } private void updateThemeColors() { - synchronized (mLock) { - final int themeColor = mContext.getColor(R.color.one_handed_tutorial_background_color); - mDefaultColor = new float[]{(Color.red(themeColor) - THEME_COLOR_OFFSET) / 255.0f, - (Color.green(themeColor) - THEME_COLOR_OFFSET) / 255.0f, - (Color.blue(themeColor) - THEME_COLOR_OFFSET) / 255.0f}; - } + final Context themedContext = new ContextThemeWrapper(mContext, + com.android.internal.R.style.Theme_DeviceDefault_DayNight); + final int themeColor = themedContext.getColor( + R.color.one_handed_tutorial_background_color); + mThemeColor = new float[]{ + adjustColor(Color.red(themeColor)), + adjustColor(Color.green(themeColor)), + adjustColor(Color.blue(themeColor))}; + } + + private float adjustColor(int origColor) { + return Math.max(origColor - THEME_COLOR_OFFSET, 0) / 255.0f; } void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG); - pw.print(innerPrefix + "mIsShowing="); - pw.println(mIsShowing); + pw.print(innerPrefix + "mBackgroundSurface="); + pw.println(mBackgroundSurface); pw.print(innerPrefix + "mBkgBounds="); pw.println(mBkgBounds); - pw.print(innerPrefix + "mDefaultColor="); - pw.println(mDefaultColor); + pw.print(innerPrefix + "mThemeColor="); + pw.println(mThemeColor); + pw.print(innerPrefix + "mTranslationFraction="); + pw.println(mTranslationFraction); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 09cde38a0cfc..b0fe856df7c8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -180,6 +180,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController> public void onStopFinished(Rect bounds) { mState.setState(STATE_NONE); notifyShortcutStateChanged(STATE_NONE); + mBackgroundPanelOrganizer.onStopFinished(); } }; @@ -223,13 +224,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController> OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor); OneHandedState transitionState = new OneHandedState(); OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context, - windowManager); + settingsUtil, windowManager); OneHandedAnimationController animationController = new OneHandedAnimationController(context); OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler, mainExecutor); OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer = - new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor); + new OneHandedBackgroundPanelOrganizer(context, displayLayout, settingsUtil, + mainExecutor); OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer( context, displayLayout, settingsUtil, animationController, tutorialHandler, oneHandedBackgroundPanelOrganizer, mainExecutor); @@ -386,6 +388,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController> mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction); mOneHandedAccessibilityUtil.announcementForScreenReader( mOneHandedAccessibilityUtil.getOneHandedStartDescription()); + mBackgroundPanelOrganizer.onStart(); mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); mTimeoutHandler.resetTimer(); mOneHandedUiEventLogger.writeEvent( @@ -423,7 +426,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> stopOneHanded(OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_OVERSPACE_OUT)); mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler); mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler); - mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer); mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallBack); if (mTaskChangeToExit) { mTaskStackListener.addListener(mTaskStackListenerCallback); @@ -469,6 +471,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController> final DisplayLayout newDisplayLayout = mDisplayController.getDisplayLayout(displayId); mDisplayAreaOrganizer.setDisplayLayout(newDisplayLayout); mTutorialHandler.onDisplayChanged(newDisplayLayout); + mBackgroundPanelOrganizer.onDisplayChanged(newDisplayLayout); } private ContentObserver getObserver(Runnable onChangeRunnable) { @@ -606,7 +609,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController> OneHandedDisplayAreaOrganizer.FEATURE_ONE_HANDED); } - if (mBackgroundPanelOrganizer.getBackgroundSurface() == null) { + if (!mBackgroundPanelOrganizer.isRegistered()) { mBackgroundPanelOrganizer.registerOrganizer( OneHandedBackgroundPanelOrganizer.FEATURE_ONE_HANDED_BACKGROUND_PANEL); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index 03a90c6d4677..c2bbd9e99bac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -135,8 +135,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { SystemProperties.getInt(ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION, animationDurationConfig); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; - mTutorialHandler = tutorialHandler; mBackgroundPanelOrganizer = oneHandedBackgroundGradientOrganizer; + mTutorialHandler = tutorialHandler; } @Override @@ -249,9 +249,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { if (animator != null) { animator.setTransitionDirection(direction) .addOneHandedAnimationCallback(mOneHandedAnimationCallback) - .addOneHandedAnimationCallback(mTutorialHandler.getAnimationCallback()) - .addOneHandedAnimationCallback( - mBackgroundPanelOrganizer.getOneHandedAnimationCallback()) + .addOneHandedAnimationCallback(mTutorialHandler) + .addOneHandedAnimationCallback(mBackgroundPanelOrganizer) .setDuration(durationMs) .start(); } @@ -267,7 +266,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { mLastVisualDisplayBounds.offsetTo(0, Math.round(mLastVisualOffset)); for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) { final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i); - cb.onStartTransition(false /* isTransitioning */); if (direction == TRANSITION_DIRECTION_TRIGGER) { cb.onStartFinished(getLastVisualDisplayBounds()); } else { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java index 5911f8d66b32..60074b8cdb47 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java @@ -20,6 +20,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController import android.annotation.IntDef; import android.content.ContentResolver; +import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings; @@ -27,6 +28,8 @@ import android.text.TextUtils; import androidx.annotation.Nullable; +import com.android.wm.shell.R; + import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -36,7 +39,6 @@ import java.lang.annotation.RetentionPolicy; */ public final class OneHandedSettingsUtil { private static final String TAG = "OneHandedSettingsUtil"; - private static final String ONE_HANDED_MODE_TARGET_NAME = ONE_HANDED_COMPONENT_NAME.getShortClassName(); @@ -204,6 +206,25 @@ public final class OneHandedSettingsUtil { Settings.Secure.ONE_HANDED_MODE_ACTIVATED, state, userId); } + /** + * Obtains one-handed mode transition duration from resource config. + * + * @return durationMs The duration in milli-seconds + */ + public int getTransitionDuration(Context context) { + return context.getResources().getInteger( + R.integer.config_one_handed_translate_animation_duration); + } + + /** + * Obtains one-handed mode offset fraction from resource config. + * + * @return fraction The fraction of offset of the whole screen. + */ + public float getTranslationFraction(Context context) { + return context.getResources().getFraction(R.fraction.config_one_handed_offset, 1, 1); + } + void dump(PrintWriter pw, String prefix, ContentResolver resolver, int userId) { final String innerPrefix = " "; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java index 97e04b5a7abd..f58c6b173af9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java @@ -32,9 +32,9 @@ import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.Rect; -import android.os.SystemProperties; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -58,66 +58,54 @@ import java.io.PrintWriter; * detach TargetViewContainer from window after exiting one handed mode. */ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, - OneHandedState.OnStateChangedListener { + OneHandedState.OnStateChangedListener, OneHandedAnimationCallback { private static final String TAG = "OneHandedTutorialHandler"; - private static final String OFFSET_PERCENTAGE = "persist.debug.one_handed_offset_percentage"; - private static final String TRANSLATE_ANIMATION_DURATION = - "persist.debug.one_handed_translate_animation_duration"; - private static final float START_TRANSITION_FRACTION = 0.7f; + private static final float START_TRANSITION_FRACTION = 0.6f; private final float mTutorialHeightRatio; private final WindowManager mWindowManager; - private final OneHandedAnimationCallback mAnimationCallback; private @OneHandedState.State int mCurrentState; private int mTutorialAreaHeight; private Context mContext; private Rect mDisplayBounds; + private ValueAnimator mAlphaAnimator; private @Nullable View mTutorialView; private @Nullable ViewGroup mTargetViewContainer; private float mAlphaTransitionStart; - private ValueAnimator mAlphaAnimator; private int mAlphaAnimationDurationMs; - public OneHandedTutorialHandler(Context context, WindowManager windowManager) { + public OneHandedTutorialHandler(Context context, OneHandedSettingsUtil settingsUtil, + WindowManager windowManager) { mContext = context; mWindowManager = windowManager; - final float offsetPercentageConfig = context.getResources().getFraction( - R.fraction.config_one_handed_offset, 1, 1); - final int sysPropPercentageConfig = SystemProperties.getInt( - OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f)); - mTutorialHeightRatio = sysPropPercentageConfig / 100.0f; - final int animationDuration = context.getResources().getInteger( - R.integer.config_one_handed_translate_animation_duration); - mAlphaAnimationDurationMs = SystemProperties.getInt(TRANSLATE_ANIMATION_DURATION, - animationDuration); - mAnimationCallback = new OneHandedAnimationCallback() { - @Override - public void onOneHandedAnimationCancel( - OneHandedAnimationController.OneHandedTransitionAnimator animator) { - if (mAlphaAnimator != null) { - mAlphaAnimator.cancel(); - } - } + mTutorialHeightRatio = settingsUtil.getTranslationFraction(context); + mAlphaAnimationDurationMs = settingsUtil.getTransitionDuration(context); + } - @Override - public void onAnimationUpdate(float xPos, float yPos) { - if (!isAttached()) { - return; - } - if (yPos < mAlphaTransitionStart) { - checkTransitionEnd(); - return; - } - if (mAlphaAnimator == null || mAlphaAnimator.isStarted() - || mAlphaAnimator.isRunning()) { - return; - } - mAlphaAnimator.start(); - } - }; + @Override + public void onOneHandedAnimationCancel( + OneHandedAnimationController.OneHandedTransitionAnimator animator) { + if (mAlphaAnimator != null) { + mAlphaAnimator.cancel(); + } + } + + @Override + public void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) { + if (!isAttached()) { + return; + } + if (yPos < mAlphaTransitionStart) { + checkTransitionEnd(); + return; + } + if (mAlphaAnimator == null || mAlphaAnimator.isStarted() || mAlphaAnimator.isRunning()) { + return; + } + mAlphaAnimator.start(); } @Override @@ -145,6 +133,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, /** * Called when onDisplayAdded() or onDisplayRemoved() callback. + * * @param displayLayout The latest {@link DisplayLayout} representing current displayId */ public void onDisplayChanged(DisplayLayout displayLayout) { @@ -196,10 +185,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, mTargetViewContainer = null; } - @Nullable OneHandedAnimationCallback getAnimationCallback() { - return mAnimationCallback; - } - /** * Returns layout params for the dismiss target, using the latest display metrics. */ @@ -264,15 +249,17 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, private void setupAlphaTransition(boolean isEntering) { final float start = isEntering ? 0.0f : 1.0f; final float end = isEntering ? 1.0f : 0.0f; + final int duration = isEntering ? mAlphaAnimationDurationMs : Math.round( + mAlphaAnimationDurationMs * (1.0f - mTutorialHeightRatio)); mAlphaAnimator = ValueAnimator.ofFloat(start, end); mAlphaAnimator.setInterpolator(new LinearInterpolator()); - mAlphaAnimator.setDuration(mAlphaAnimationDurationMs); + mAlphaAnimator.setDuration(duration); mAlphaAnimator.addUpdateListener( animator -> mTargetViewContainer.setAlpha((float) animator.getAnimatedValue())); } private void checkTransitionEnd() { - if (mAlphaAnimator != null && mAlphaAnimator.isRunning()) { + if (mAlphaAnimator != null && (mAlphaAnimator.isRunning() || mAlphaAnimator.isStarted())) { mAlphaAnimator.end(); mAlphaAnimator.removeAllUpdateListeners(); mAlphaAnimator = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index dff5577f5f20..29326ec90e31 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -25,6 +25,7 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCRE import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityThread; import android.content.BroadcastReceiver; import android.content.Context; @@ -315,7 +316,7 @@ public class SplashscreenContentDrawer { private Drawable mOverlayDrawable; private int mSuggestType; private int mThemeColor; - private Drawable mFinalIconDrawable; + private Drawable[] mFinalIconDrawables; private int mFinalIconSize = mIconSize; StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) { @@ -347,12 +348,13 @@ public class SplashscreenContentDrawer { animationDuration = 0; mFinalIconSize = 0; } else if (mTmpAttrs.mSplashScreenIcon != null) { - // replaced icon, don't process + // Using the windowSplashScreenAnimatedIcon attribute iconDrawable = mTmpAttrs.mSplashScreenIcon; animationDuration = mTmpAttrs.mAnimationDuration; // There is no background below the icon, so scale the icon up - if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT) { + if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT + || mTmpAttrs.mIconBgColor == mThemeColor) { mFinalIconSize *= NO_BACKGROUND_SCALE; } createIconDrawable(iconDrawable, false); @@ -383,7 +385,7 @@ public class SplashscreenContentDrawer { animationDuration = 0; } - return fillViewWithIcon(mFinalIconSize, mFinalIconDrawable, animationDuration); + return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration); } private class ShapeIconFactory extends BaseIconFactory { @@ -394,12 +396,11 @@ public class SplashscreenContentDrawer { private void createIconDrawable(Drawable iconDrawable, boolean legacy) { if (legacy) { - mFinalIconDrawable = SplashscreenIconDrawableFactory.makeLegacyIconDrawable( + mFinalIconDrawables = SplashscreenIconDrawableFactory.makeLegacyIconDrawable( iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler); } else { - mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable( - mTmpAttrs.mIconBgColor != Color.TRANSPARENT - ? mTmpAttrs.mIconBgColor : mThemeColor, + mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable( + mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler); } } @@ -461,18 +462,24 @@ public class SplashscreenContentDrawer { return true; } - private SplashScreenView fillViewWithIcon(int iconSize, Drawable iconDrawable, + private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable, int animationDuration) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon"); - final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext); - builder.setBackgroundColor(mThemeColor); - builder.setOverlayDrawable(mOverlayDrawable); + Drawable foreground = null; + Drawable background = null; if (iconDrawable != null) { - builder.setIconSize(iconSize) - .setIconBackground(mTmpAttrs.mIconBgColor) - .setCenterViewDrawable(iconDrawable) - .setAnimationDurationMillis(animationDuration); + foreground = iconDrawable.length > 0 ? iconDrawable[0] : null; + background = iconDrawable.length > 1 ? iconDrawable[1] : null; } + + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon"); + final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext) + .setBackgroundColor(mThemeColor) + .setOverlayDrawable(mOverlayDrawable) + .setIconSize(iconSize) + .setIconBackground(background) + .setCenterViewDrawable(foreground) + .setAnimationDurationMillis(animationDuration); + if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN && mTmpAttrs.mBrandingImage != null) { builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java index ba9123dca999..951b97e791c9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java @@ -22,9 +22,11 @@ import android.animation.Animator; import android.animation.ValueAnimator; import android.annotation.ColorInt; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; @@ -33,7 +35,6 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.Animatable; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Trace; @@ -44,32 +45,55 @@ import com.android.internal.R; /** * Creating a lightweight Drawable object used for splash screen. + * * @hide */ public class SplashscreenIconDrawableFactory { - static Drawable makeIconDrawable(@ColorInt int backgroundColor, + /** + * @return An array containing the foreground drawable at index 0 and if needed a background + * drawable at index 1. + */ + static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor, @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize, Handler splashscreenWorkerHandler) { + Drawable foreground; + Drawable background = null; + boolean drawBackground = + backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor; + if (foregroundDrawable instanceof Animatable) { - return new AnimatableIconAnimateListener(backgroundColor, foregroundDrawable); + foreground = new AnimatableIconAnimateListener(foregroundDrawable); } else if (foregroundDrawable instanceof AdaptiveIconDrawable) { - return new ImmobileIconDrawable(foregroundDrawable, + // If the icon is Adaptive, we already use the icon background. + drawBackground = false; + foreground = new ImmobileIconDrawable(foregroundDrawable, srcIconSize, iconSize, splashscreenWorkerHandler); } else { - // single layer icon - return new ImmobileIconDrawable(new AdaptiveIconDrawable( - new ColorDrawable(backgroundColor), foregroundDrawable), + // Adaptive icon don't handle transparency so we draw the background of the adaptive + // icon with the same color as the window background color instead of using two layers + foreground = new ImmobileIconDrawable( + new AdaptiveForegroundDrawable(foregroundDrawable), srcIconSize, iconSize, splashscreenWorkerHandler); } + + if (drawBackground) { + background = new MaskBackgroundDrawable(backgroundColor); + } + + return new Drawable[]{foreground, background}; } - static Drawable makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize, + static Drawable[] makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize, int iconSize, Handler splashscreenWorkerHandler) { - return new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize, - splashscreenWorkerHandler); + return new Drawable[]{new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize, + splashscreenWorkerHandler)}; } + /** + * Drawable pre-drawing the scaled icon in a separate thread to increase the speed of the + * final drawing. + */ private static class ImmobileIconDrawable extends Drawable { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG); @@ -121,8 +145,10 @@ public class SplashscreenIconDrawableFactory { } } - // Base class the draw the circle background - private abstract static class MaskBackgroundDrawable extends Drawable { + /** + * Base class the draw a background clipped by the system mask. + */ + public static class MaskBackgroundDrawable extends Drawable { private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE; private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f; static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE); @@ -132,17 +158,24 @@ public class SplashscreenIconDrawableFactory { private static Path sMask; private final Path mMaskScaleOnly; private final Matrix mMaskMatrix; - private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG - | Paint.FILTER_BITMAP_FLAG); - MaskBackgroundDrawable(@ColorInt int backgroundColor) { + @Nullable + private final Paint mBackgroundPaint; + + public MaskBackgroundDrawable(@ColorInt int backgroundColor) { final Resources r = Resources.getSystem(); sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask)); Path mask = new Path(sMask); mMaskScaleOnly = new Path(mask); mMaskMatrix = new Matrix(); - mPaint.setColor(backgroundColor); - mPaint.setStyle(Paint.Style.FILL); + if (backgroundColor != Color.TRANSPARENT) { + mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG + | Paint.FILTER_BITMAP_FLAG); + mBackgroundPaint.setColor(backgroundColor); + mBackgroundPaint.setStyle(Paint.Style.FILL); + } else { + mBackgroundPaint = null; + } } @Override @@ -162,40 +195,80 @@ public class SplashscreenIconDrawableFactory { @Override public void draw(Canvas canvas) { canvas.clipPath(mMaskScaleOnly); - if (mMaskScaleOnly != null) { - canvas.drawPath(mMaskScaleOnly, mPaint); + if (mBackgroundPaint != null) { + canvas.drawPath(mMaskScaleOnly, mBackgroundPaint); } } @Override public void setAlpha(int alpha) { - mPaint.setAlpha(alpha); + if (mBackgroundPaint != null) { + mBackgroundPaint.setAlpha(alpha); + } } @Override public int getOpacity() { return PixelFormat.RGBA_8888; } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + } + } + + private static class AdaptiveForegroundDrawable extends MaskBackgroundDrawable { + + @NonNull + protected final Drawable mForegroundDrawable; + private final Rect mTmpOutRect = new Rect(); + + AdaptiveForegroundDrawable(@NonNull Drawable foregroundDrawable) { + super(Color.TRANSPARENT); + mForegroundDrawable = foregroundDrawable; + } + + @Override + protected void updateLayerBounds(Rect bounds) { + super.updateLayerBounds(bounds); + int cX = bounds.width() / 2; + int cY = bounds.height() / 2; + + int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2)); + int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2)); + final Rect outRect = mTmpOutRect; + outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight); + if (mForegroundDrawable != null) { + mForegroundDrawable.setBounds(outRect); + } + invalidateSelf(); + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + mForegroundDrawable.draw(canvas); + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + mForegroundDrawable.setColorFilter(colorFilter); + } } /** * A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this * drawable masked by config_icon_mask. */ - private static class AnimatableIconAnimateListener extends MaskBackgroundDrawable + private static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable implements SplashScreenView.IconAnimateListener { - private final Drawable mForegroundDrawable; private Animatable mAnimatableIcon; private Animator mIconAnimator; private boolean mAnimationTriggered; - private final Rect mTmpOutRect = new Rect(); - AnimatableIconAnimateListener(@ColorInt int backgroundColor, Drawable foregroundDrawable) { - super(backgroundColor); - mForegroundDrawable = foregroundDrawable; - if (mForegroundDrawable != null) { - mForegroundDrawable.setCallback(mCallback); - } + AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) { + super(foregroundDrawable); + mForegroundDrawable.setCallback(mCallback); } @Override @@ -231,22 +304,6 @@ public class SplashscreenIconDrawableFactory { return true; } - @Override - protected void updateLayerBounds(Rect bounds) { - super.updateLayerBounds(bounds); - int cX = bounds.width() / 2; - int cY = bounds.height() / 2; - - int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2)); - int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2)); - final Rect outRect = mTmpOutRect; - outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight); - if (mForegroundDrawable != null) { - mForegroundDrawable.setBounds(outRect); - } - invalidateSelf(); - } - private final Callback mCallback = new Callback() { @Override public void invalidateDrawable(@NonNull Drawable who) { @@ -276,19 +333,8 @@ public class SplashscreenIconDrawableFactory { @Override public void draw(Canvas canvas) { + ensureAnimationStarted(); super.draw(canvas); - if (mForegroundDrawable != null) { - ensureAnimationStarted(); - mForegroundDrawable.draw(canvas); - } - } - - @Override - public void setColorFilter(ColorFilter colorFilter) { - if (mForegroundDrawable != null) { - mForegroundDrawable.setColorFilter(colorFilter); - } } } - } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java index 3f47c040dd8d..99c610765c04 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java @@ -22,7 +22,10 @@ import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED_BACKGROUND_ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.testing.AndroidTestingRunner; @@ -54,17 +57,17 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase { private OneHandedBackgroundPanelOrganizer mSpiedBackgroundPanelOrganizer; private WindowContainerToken mToken; private SurfaceControl mLeash; - private TestableLooper mTestableLooper; @Mock IWindowContainerToken mMockRealToken; @Mock DisplayController mMockDisplayController; + @Mock + OneHandedSettingsUtil mMockSettingsUtil; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mTestableLooper = TestableLooper.get(this); mToken = new WindowContainerToken(mMockRealToken); mLeash = new SurfaceControl(); mDisplay = mContext.getDisplay(); @@ -74,32 +77,36 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase { FEATURE_ONE_HANDED_BACKGROUND_PANEL); mSpiedBackgroundPanelOrganizer = spy( - new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, Runnable::run)); + new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, mMockSettingsUtil, + Runnable::run)); + mSpiedBackgroundPanelOrganizer.onDisplayChanged(mDisplayLayout); } @Test public void testOnDisplayAreaAppeared() { mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash); - mTestableLooper.processAllMessages(); - assertThat(mSpiedBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull(); + assertThat(mSpiedBackgroundPanelOrganizer.isRegistered()).isTrue(); + verify(mSpiedBackgroundPanelOrganizer, never()).showBackgroundPanelLayer(); } @Test public void testShowBackgroundLayer() { - mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash); - mSpiedBackgroundPanelOrganizer.showBackgroundPanelLayer(); - mTestableLooper.processAllMessages(); + mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, null); + mSpiedBackgroundPanelOrganizer.onStart(); - assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isTrue(); + verify(mSpiedBackgroundPanelOrganizer).showBackgroundPanelLayer(); } @Test public void testRemoveBackgroundLayer() { mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash); + + assertThat(mSpiedBackgroundPanelOrganizer.isRegistered()).isNotNull(); + + reset(mSpiedBackgroundPanelOrganizer); mSpiedBackgroundPanelOrganizer.removeBackgroundPanelLayer(); - mTestableLooper.processAllMessages(); - assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isFalse(); + assertThat(mSpiedBackgroundPanelOrganizer.mBackgroundSurface).isNull(); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index b224ae6a19b5..911fe0753845 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -110,7 +110,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>()); when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true); - when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash); + when(mMockBackgroundOrganizer.isRegistered()).thenReturn(true); when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn( mDefaultEnabled); when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn( diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java index e61f0617852a..bea69c5d80ef 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java @@ -102,7 +102,7 @@ public class OneHandedStateTest extends OneHandedTestCase { when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>()); - when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash); + when(mMockBackgroundOrganizer.isRegistered()).thenReturn(true); when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn( mDefaultEnabled); when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn( diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java index ae1d3b2a4c41..b1434ca325b7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java @@ -66,7 +66,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { mDisplayLayout = new DisplayLayout(mContext, mDisplay); mSpiedTransitionState = spy(new OneHandedState()); mSpiedTutorialHandler = spy( - new OneHandedTutorialHandler(mContext, mMockWindowManager)); + new OneHandedTutorialHandler(mContext, mMockSettingsUtil, mMockWindowManager)); mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor); } diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index d746c850a018..37054b8383b1 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -1573,6 +1573,9 @@ public class ExifInterface { if (isFdDuped) { closeFileDescriptor(fileDescriptor); } + if (modernFd != null) { + modernFd.close(); + } } } @@ -2554,12 +2557,13 @@ public class ExifInterface { private void initForFilename(String filename) throws IOException { FileInputStream in = null; + ParcelFileDescriptor modernFd = null; mAssetInputStream = null; mFilename = filename; mIsInputStream = false; try { in = new FileInputStream(filename); - ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(in.getFD()); + modernFd = FileUtils.convertToModernFd(in.getFD()); if (modernFd != null) { closeQuietly(in); in = new FileInputStream(modernFd.getFileDescriptor()); @@ -2570,6 +2574,9 @@ public class ExifInterface { loadAttributes(in); } finally { closeQuietly(in); + if (modernFd != null) { + modernFd.close(); + } } } diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index 2943eee5b1da..a15529e99d15 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.SystemProperties; import android.text.TextUtils; +import android.util.Log; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -52,6 +53,8 @@ import java.util.Map; * frame and meta data from an input media file. */ public class MediaMetadataRetriever implements AutoCloseable { + private static final String TAG = "MediaMetadataRetriever"; + // borrowed from ExoPlayer private static final String[] STANDARD_GENRES = new String[] { // These are the official ID3v1 genres. @@ -301,11 +304,15 @@ public class MediaMetadataRetriever implements AutoCloseable { */ public void setDataSource(FileDescriptor fd, long offset, long length) throws IllegalArgumentException { - ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd); - if (modernFd == null) { - _setDataSource(fd, offset, length); - } else { - _setDataSource(modernFd.getFileDescriptor(), offset, length); + + try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) { + if (modernFd == null) { + _setDataSource(fd, offset, length); + } else { + _setDataSource(modernFd.getFileDescriptor(), offset, length); + } + } catch (IOException e) { + Log.w(TAG, "Ignoring IO error while setting data source", e); } } diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 4f761ba0bf6a..26eb2a9dc109 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1271,11 +1271,14 @@ public class MediaPlayer extends PlayerBase */ public void setDataSource(FileDescriptor fd, long offset, long length) throws IOException, IllegalArgumentException, IllegalStateException { - ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd); - if (modernFd == null) { - _setDataSource(fd, offset, length); - } else { - _setDataSource(modernFd.getFileDescriptor(), offset, length); + try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) { + if (modernFd == null) { + _setDataSource(fd, offset, length); + } else { + _setDataSource(modernFd.getFileDescriptor(), offset, length); + } + } catch (IOException e) { + Log.w(TAG, "Ignoring IO error while setting data source", e); } } diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index 628f7eef84f9..7f7fb6023b07 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -292,8 +292,7 @@ public final class MediaRouter2Manager { } synchronized (mRoutesLock) { for (MediaRoute2Info route : mRoutes.values()) { - if (sessionInfo.getSelectedRoutes().contains(route.getId()) - || sessionInfo.getTransferableRoutes().contains(route.getId())) { + if (sessionInfo.getTransferableRoutes().contains(route.getId())) { routes.add(route); continue; } diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 95a2da9226d9..51a0c99af66e 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -111,8 +111,7 @@ APerformanceHintManager* APerformanceHintManager::create(sp<IHintManager> manage return nullptr; } if (preferredRateNanos <= 0) { - ALOGE("%s: PerformanceHint invalid preferred rate.", __FUNCTION__); - return nullptr; + preferredRateNanos = -1L; } return new APerformanceHintManager(std::move(manager), preferredRateNanos); } diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml index 3d62af020627..9d3ce348f013 100644 --- a/packages/EasterEgg/AndroidManifest.xml +++ b/packages/EasterEgg/AndroidManifest.xml @@ -1,26 +1,28 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.egg" - android:versionCode="1" + android:versionCode="12" android:versionName="1.0"> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <!-- used for cat notifications --> <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" /> + <!-- used to save cat images --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <!-- controls --> <uses-permission android:name="android.permission.BIND_CONTROLS" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> - - <activity android:name=".quares.QuaresActivity" + <activity + android:name=".quares.QuaresActivity" + android:exported="true" android:icon="@drawable/q_icon" android:label="@string/q_egg_name" - android:exported="true" android:theme="@style/QuaresTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -29,9 +31,9 @@ <activity android:name=".paint.PaintActivity" android:configChanges="orientation|keyboardHidden|screenSize|uiMode" + android:exported="true" android:icon="@drawable/p_icon" android:label="@string/p_egg_name" - android:exported="true" android:theme="@style/AppTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -39,13 +41,15 @@ </activity> <!-- Android N easter egg bits --> - <activity android:name=".neko.NekoLand" - android:theme="@android:style/Theme.Material.NoActionBar" + <activity + android:name=".neko.NekoLand" android:exported="true" - android:label="@string/app_name"> + android:label="@string/app_name" + android:theme="@android:style/Theme.Material.NoActionBar"> <intent-filter> <action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" /> <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> @@ -54,25 +58,24 @@ <service android:name=".neko.NekoService" android:enabled="true" - android:permission="android.permission.BIND_JOB_SERVICE" - android:exported="true" > - </service> - + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" /> <!-- Used to show over lock screen --> - <activity android:name=".neko.NekoLockedActivity" + <activity + android:name=".neko.NekoLockedActivity" android:excludeFromRecents="true" android:exported="true" - android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar" - android:showOnLockScreen="true" /> - + android:showOnLockScreen="true" + android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar" /> <!-- Used to enable easter egg --> - <activity android:name=".neko.NekoActivationActivity" + <activity + android:name=".ComponentActivationActivity" android:excludeFromRecents="true" android:exported="true" - android:theme="@android:style/Theme.NoDisplay" - > + android:theme="@android:style/Theme.NoDisplay"> <intent-filter> - <action android:name="android.intent.action.MAIN"/> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.android.internal.category.PLATLOGO" /> </intent-filter> @@ -81,37 +84,66 @@ <!-- The quick settings tile, disabled by default --> <service android:name=".neko.NekoTile" - android:permission="android.permission.BIND_QUICK_SETTINGS_TILE" - android:icon="@drawable/stat_icon" android:enabled="false" android:exported="true" - android:label="@string/default_tile_name"> + android:icon="@drawable/stat_icon" + android:label="@string/default_tile_name" + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> <intent-filter> <action android:name="android.service.quicksettings.action.QS_TILE" /> </intent-filter> </service> - - <service android:name=".neko.NekoControlsService" - android:permission="android.permission.BIND_CONTROLS" - android:label="@string/r_egg_name" - android:icon="@drawable/ic_fullcat_icon" + <service + android:name=".neko.NekoControlsService" android:enabled="false" - android:exported="true"> + android:exported="true" + android:icon="@drawable/ic_fullcat_icon" + android:label="@string/r_egg_name" + android:permission="android.permission.BIND_CONTROLS"> <intent-filter> <action android:name="android.service.controls.ControlsProviderService" /> </intent-filter> - </service> - - <!-- FileProvider for sending pictures --> + </service> <!-- FileProvider for sending pictures --> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.android.egg.fileprovider" - android:grantUriPermissions="true" - android:exported="false"> + android:exported="false" + android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider> + + <!-- Android S easter egg bits --> + + <!-- List of all system theme colors on the device. --> + <activity + android:name=".widget.PaintChipsActivity" + android:theme="@android:style/Theme.Material.Wallpaper.NoTitleBar" + android:configChanges="orientation|keyboardHidden|screenSize|uiMode" + android:label="@string/s_egg_name" + android:enabled="false" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + + <!-- Homescreen widget also showing paint chips (may be affected by the exact position in + the workspace) --> + <receiver + android:name=".widget.PaintChipsWidget" + android:label="@string/s_egg_name" + android:exported="true" + android:enabled="false"> + <intent-filter> + <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> + </intent-filter> + + <meta-data + android:name="android.appwidget.provider" + android:resource="@xml/paint_chips_widget_info" /> + </receiver> </application> </manifest> diff --git a/packages/EasterEgg/build.gradle b/packages/EasterEgg/build.gradle index 20b469898498..0565369fe81f 100644 --- a/packages/EasterEgg/build.gradle +++ b/packages/EasterEgg/build.gradle @@ -7,8 +7,8 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:7.0.0-alpha08' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30" } } @@ -62,6 +62,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + buildFeatures { + viewBinding true + } } @@ -74,6 +77,7 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.6' implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}" implementation "androidx.dynamicanimation:dynamicanimation:${ANDROID_X_VERSION}" + implementation 'com.google.android.material:material:1.3.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/packages/EasterEgg/gradle.properties b/packages/EasterEgg/gradle.properties index e8e6450e2943..0b5a73677b3b 100644 --- a/packages/EasterEgg/gradle.properties +++ b/packages/EasterEgg/gradle.properties @@ -19,5 +19,5 @@ android.enableJetifier=true kotlin.code.style=official ANDROID_X_VERSION=1+ -COMPILE_SDK=android-30 +COMPILE_SDK=android-S BUILD_TOOLS_VERSION=28.0.3 diff --git a/packages/EasterEgg/res/drawable/android_s.xml b/packages/EasterEgg/res/drawable/android_s.xml new file mode 100644 index 000000000000..9cecab103ac8 --- /dev/null +++ b/packages/EasterEgg/res/drawable/android_s.xml @@ -0,0 +1,23 @@ +<vector android:height="108dp" android:viewportHeight="48" + android:viewportWidth="48" android:width="108dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <group> + <clip-path android:pathData="M17,14h14v20h-14z"/> + <path android:fillColor="#00000000" + android:pathData="M18,21C18,21.7956 18.3161,22.5587 18.8787,23.1213C19.4413,23.6839 20.2044,24 21,24H27C27.7956,24 28.5587,24.3161 29.1213,24.8787C29.6839,25.4413 30,26.2044 30,27" + android:strokeColor="#ffffff" android:strokeWidth="2"/> + <path android:fillColor="#ffffff" android:pathData="M22,21C22.5523,21 23,20.5523 23,20C23,19.4477 22.5523,19 22,19C21.4477,19 21,19.4477 21,20C21,20.5523 21.4477,21 22,21Z"/> + <path android:fillColor="#ffffff" android:pathData="M26,21C26.5523,21 27,20.5523 27,20C27,19.4477 26.5523,19 26,19C25.4477,19 25,19.4477 25,20C25,20.5523 25.4477,21 26,21Z"/> + <path android:fillColor="#00000000" + android:pathData="M19.5,16.5L18,15" + android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/> + <path android:fillColor="#00000000" + android:pathData="M28.5,16.5L30,15" + android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/> + <path android:fillColor="#00000000" + android:pathData="M29.92,20C29.8637,19.6605 29.7801,19.3261 29.67,19C29.205,17.6561 28.2777,16.5211 27.0536,15.7973C25.8294,15.0735 24.388,14.8081 22.9864,15.0483C21.5847,15.2885 20.314,16.0188 19.4007,17.1088C18.4874,18.1989 17.991,19.5779 18,21" + android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/> + <path android:fillColor="#00000000" + android:pathData="M18.08,28C18.1363,28.3395 18.2199,28.6739 18.33,29C18.795,30.3439 19.7223,31.4789 20.9464,32.2027C22.1705,32.9265 23.612,33.1919 25.0136,32.9517C26.4153,32.7115 27.686,31.9812 28.5993,30.8912C29.5126,29.8011 30.009,28.4221 30,27" + android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/> + </group> +</vector> diff --git a/packages/EasterEgg/res/drawable/icon.xml b/packages/EasterEgg/res/drawable/icon.xml index 7f8d4fa8833f..7054962b3503 100644 --- a/packages/EasterEgg/res/drawable/icon.xml +++ b/packages/EasterEgg/res/drawable/icon.xml @@ -15,5 +15,5 @@ Copyright (C) 2018 The Android Open Source Project --> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@drawable/icon_bg"/> - <foreground android:drawable="@drawable/android_11_dial"/> + <foreground android:drawable="@drawable/android_s"/> </adaptive-icon> diff --git a/packages/EasterEgg/res/drawable/icon_bg.xml b/packages/EasterEgg/res/drawable/icon_bg.xml index 31b2a7f9a333..d08e160ea312 100644 --- a/packages/EasterEgg/res/drawable/icon_bg.xml +++ b/packages/EasterEgg/res/drawable/icon_bg.xml @@ -14,5 +14,5 @@ Copyright (C) 2018 The Android Open Source Project limitations under the License. --> <color xmlns:android="http://schemas.android.com/apk/res/android" - android:color="#073042" /> + android:color="@android:color/system_accent2_500" /> diff --git a/packages/EasterEgg/res/drawable/roundrect.xml b/packages/EasterEgg/res/drawable/roundrect.xml new file mode 100644 index 000000000000..070adadf3814 --- /dev/null +++ b/packages/EasterEgg/res/drawable/roundrect.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="#FF000000" /> + <corners + android:radius="12dp" /> +</shape>
\ No newline at end of file diff --git a/packages/EasterEgg/res/layout/paint_chip.xml b/packages/EasterEgg/res/layout/paint_chip.xml new file mode 100644 index 000000000000..d5745b94d163 --- /dev/null +++ b/packages/EasterEgg/res/layout/paint_chip.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 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. +--> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/chip" + android:layout_width="10dp" android:layout_height="10dp" + android:layout_gravity="fill" android:layout_columnWeight="1" android:layout_rowWeight="1" + android:text="A1-500" + android:backgroundTint="@android:color/system_accent1_500" + android:background="@drawable/roundrect" + android:gravity="center" + android:textColor="?android:attr/textColorPrimary" + android:fontFamily="?android:attr/textAppearanceLarge" + android:layout_margin="2dp" + android:singleLine="true" + />
\ No newline at end of file diff --git a/packages/EasterEgg/res/layout/paint_chips_grid.xml b/packages/EasterEgg/res/layout/paint_chips_grid.xml new file mode 100644 index 000000000000..79f701322149 --- /dev/null +++ b/packages/EasterEgg/res/layout/paint_chips_grid.xml @@ -0,0 +1,25 @@ +<!-- + Copyright (C) 2021 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. +--> +<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/paint_grid" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="0dp" + android:orientation="vertical" + android:alignmentMode="alignBounds" + android:rowOrderPreserved="false" + > +</GridLayout> diff --git a/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml b/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml new file mode 100644 index 000000000000..9893ec054992 --- /dev/null +++ b/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml @@ -0,0 +1,79 @@ +<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="300dp" + android:layout_height="50dp" + android:alignmentMode="alignBounds" + android:columnCount="5" + android:padding="0dp" + android:rowCount="1" + android:rowOrderPreserved="false"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_gravity="fill" + android:layout_margin="2dp" + android:background="@drawable/roundrect" + android:backgroundTint="@android:color/system_neutral1_500" + android:fontFamily="?android:attr/textAppearanceLarge" + android:gravity="center" + android:text="N1-500" + android:textColor="?android:attr/textColorPrimary" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_gravity="fill" + android:layout_margin="2dp" + android:background="@drawable/roundrect" + android:backgroundTint="@android:color/system_neutral2_500" + android:fontFamily="?android:attr/textAppearanceLarge" + android:gravity="center" + android:text="N2-500" + android:textColor="?android:attr/textColorPrimary" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_gravity="fill" + android:layout_margin="2dp" + android:background="@drawable/roundrect" + android:backgroundTint="@android:color/system_accent1_500" + android:fontFamily="?android:attr/textAppearanceLarge" + android:gravity="center" + android:text="A1-500" + android:textColor="?android:attr/textColorPrimary" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_gravity="fill" + android:layout_margin="2dp" + android:background="@drawable/roundrect" + android:backgroundTint="@android:color/system_accent2_500" + android:fontFamily="?android:attr/textAppearanceLarge" + android:gravity="center" + android:text="A2-500" + android:textColor="?android:attr/textColorPrimary" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_gravity="fill" + android:layout_margin="2dp" + android:background="@drawable/roundrect" + android:backgroundTint="@android:color/system_accent3_500" + android:fontFamily="?android:attr/textAppearanceLarge" + android:gravity="center" + android:text="A3-500" + android:textColor="?android:attr/textColorPrimary" /> +</GridLayout> diff --git a/packages/EasterEgg/res/values-night/themes.xml b/packages/EasterEgg/res/values-night/themes.xml new file mode 100644 index 000000000000..83ec7a5557c3 --- /dev/null +++ b/packages/EasterEgg/res/values-night/themes.xml @@ -0,0 +1,7 @@ +<resources> + + <style name="ThemeOverlay.EasterEgg.AppWidgetContainer" parent=""> + <item name="appWidgetBackgroundColor">@color/light_blue_900</item> + <item name="appWidgetTextColor">@color/light_blue_200</item> + </style> +</resources>
\ No newline at end of file diff --git a/packages/EasterEgg/res/values/attrs.xml b/packages/EasterEgg/res/values/attrs.xml new file mode 100644 index 000000000000..97531a25692c --- /dev/null +++ b/packages/EasterEgg/res/values/attrs.xml @@ -0,0 +1,6 @@ +<resources> + <declare-styleable name="AppWidgetAttrs"> + <attr name="appWidgetBackgroundColor" format="color" /> + <attr name="appWidgetTextColor" format="color" /> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/packages/EasterEgg/res/values/colors.xml b/packages/EasterEgg/res/values/colors.xml index 1a5388b738dd..d79e83b8af0c 100644 --- a/packages/EasterEgg/res/values/colors.xml +++ b/packages/EasterEgg/res/values/colors.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2018 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,4 +17,8 @@ <color name="toolbar_bg_color">#FFDDDDDD</color> <color name="paper_color">#FFFFFFFF</color> <color name="paint_color">#FF000000</color> + <color name="light_blue_50">#FFE1F5FE</color> + <color name="light_blue_200">#FF81D4FA</color> + <color name="light_blue_600">#FF039BE5</color> + <color name="light_blue_900">#FF01579B</color> </resources>
\ No newline at end of file diff --git a/packages/EasterEgg/res/values/dimens.xml b/packages/EasterEgg/res/values/dimens.xml index e9dcebd27f7b..0de2c3cb7b43 100644 --- a/packages/EasterEgg/res/values/dimens.xml +++ b/packages/EasterEgg/res/values/dimens.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,4 +15,10 @@ Copyright (C) 2016 The Android Open Source Project --> <resources xmlns:android="http://schemas.android.com/apk/res/android"> <dimen name="neko_display_size">64dp</dimen> + + <!-- +Refer to App Widget Documentation for margin information +http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout + --> + <dimen name="widget_margin">0dp</dimen> </resources> diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml index 25f94215d433..743947ad281e 100644 --- a/packages/EasterEgg/res/values/strings.xml +++ b/packages/EasterEgg/res/values/strings.xml @@ -14,7 +14,7 @@ Copyright (C) 2018 The Android Open Source Project limitations under the License. --> <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <string name="app_name" translatable="false">Android R Easter Egg</string> + <string name="app_name" translatable="false">Android S Easter Egg</string> <!-- name of the Q easter egg, a nonogram-style icon puzzle --> <string name="q_egg_name" translatable="false">Icon Quiz</string> @@ -23,4 +23,8 @@ Copyright (C) 2018 The Android Open Source Project <string name="p_egg_name" translatable="false">PAINT.APK</string> <string name="r_egg_name" translatable="false">Cat Controls</string> + + <!-- name of the S easter egg, a widget that displays the system color palette + in a manner similar to a set of paint samples from a hardware store --> + <string name="s_egg_name" translatable="false">Paint Chips</string> </resources> diff --git a/packages/EasterEgg/res/values/themes.xml b/packages/EasterEgg/res/values/themes.xml new file mode 100644 index 000000000000..5b163043a356 --- /dev/null +++ b/packages/EasterEgg/res/values/themes.xml @@ -0,0 +1,7 @@ +<resources> + + <style name="ThemeOverlay.EasterEgg.AppWidgetContainer" parent=""> + <item name="appWidgetBackgroundColor">@color/light_blue_600</item> + <item name="appWidgetTextColor">@color/light_blue_50</item> + </style> +</resources>
\ No newline at end of file diff --git a/packages/EasterEgg/res/xml/paint_chips_widget_info.xml b/packages/EasterEgg/res/xml/paint_chips_widget_info.xml new file mode 100644 index 000000000000..7780a757f01c --- /dev/null +++ b/packages/EasterEgg/res/xml/paint_chips_widget_info.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 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. +--> +<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" + android:initialLayout="@layout/paint_chip" + android:previewLayout="@layout/paint_chips_widget_preview" + android:minWidth="50dp" + android:minHeight="50dp" + android:resizeMode="horizontal|vertical" + android:updatePeriodMillis="86400000" + android:widgetCategory="home_screen"></appwidget-provider>
\ No newline at end of file diff --git a/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java new file mode 100644 index 000000000000..5820b5a75894 --- /dev/null +++ b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 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.egg; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.pm.PackageManager; +import android.provider.Settings; +import android.util.Log; +import android.widget.Toast; + +import com.android.egg.neko.NekoControlsService; +import com.android.egg.widget.PaintChipsActivity; +import com.android.egg.widget.PaintChipsWidget; + +/** + * Launched from the PlatLogoActivity. Enables everything else in this easter egg. + */ +public class ComponentActivationActivity extends Activity { + private static final String TAG = "EasterEgg"; + + private static final String S_EGG_UNLOCK_SETTING = "egg_mode_s"; + + private void toastUp(String s) { + Toast toast = Toast.makeText(this, s, Toast.LENGTH_SHORT); + toast.show(); + } + + @Override + public void onStart() { + super.onStart(); + + final PackageManager pm = getPackageManager(); + final ComponentName[] cns = new ComponentName[] { + new ComponentName(this, NekoControlsService.class), + new ComponentName(this, PaintChipsActivity.class), + new ComponentName(this, PaintChipsWidget.class) + }; + final long unlockValue = Settings.System.getLong(getContentResolver(), + S_EGG_UNLOCK_SETTING, 0); + for (ComponentName cn : cns) { + final boolean componentEnabled = pm.getComponentEnabledSetting(cn) + == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + if (unlockValue == 0) { + if (componentEnabled) { + Log.v(TAG, "Disabling component: " + cn); + pm.setComponentEnabledSetting(cn, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + //toastUp("\uD83D\uDEAB"); + } else { + Log.v(TAG, "Already disabled: " + cn); + } + } else { + if (!componentEnabled) { + Log.v(TAG, "Enabling component: " + cn); + pm.setComponentEnabledSetting(cn, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + //toastUp("\uD83D\uDC31"); + } else { + Log.v(TAG, "Already enabled: " + cn); + } + } + } + + finish(); + } +} diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java b/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java deleted file mode 100644 index df461c6878f0..000000000000 --- a/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2016 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.egg.neko; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.provider.Settings; -import android.util.Log; -import android.widget.Toast; - -import com.android.internal.logging.MetricsLogger; - -public class NekoActivationActivity extends Activity { - private static final String R_EGG_UNLOCK_SETTING = "egg_mode_r"; - - private void toastUp(String s) { - Toast toast = Toast.makeText(this, s, Toast.LENGTH_SHORT); - toast.show(); - } - - @Override - public void onStart() { - super.onStart(); - - final PackageManager pm = getPackageManager(); - final ComponentName cn = new ComponentName(this, NekoControlsService.class); - final boolean componentEnabled = pm.getComponentEnabledSetting(cn) - == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - if (Settings.System.getLong(getContentResolver(), - R_EGG_UNLOCK_SETTING, 0) == 0) { - if (componentEnabled) { - Log.v("Neko", "Disabling controls."); - pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP); - MetricsLogger.histogram(this, "egg_neko_enable", 0); - toastUp("\uD83D\uDEAB"); - } else { - Log.v("Neko", "Controls already disabled."); - } - } else { - if (!componentEnabled) { - Log.v("Neko", "Enabling controls."); - pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, - PackageManager.DONT_KILL_APP); - MetricsLogger.histogram(this, "egg_neko_enable", 1); - toastUp("\uD83D\uDC31"); - } else { - Log.v("Neko", "Controls already enabled."); - } - } - finish(); - } -} diff --git a/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt new file mode 100644 index 000000000000..8799aecf5516 --- /dev/null +++ b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2021 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.egg.widget + +import android.app.Activity +import android.content.res.Configuration +import android.os.Bundle +import android.widget.FrameLayout + +/** + * Activity to show off the current dynamic system theme in all its glory. + */ +class PaintChipsActivity : Activity() { + private lateinit var layout: FrameLayout + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + window.navigationBarColor = 0 + window.statusBarColor = 0 + actionBar?.hide() + + layout = FrameLayout(this) + layout.setPadding(dp2px(8f), dp2px(8f), dp2px(8f), dp2px(8f)) + rebuildGrid() + + setContentView(layout) + } + + fun dp2px(dp: Float): Int { + return (dp * resources.displayMetrics.density).toInt() + } + + override fun onResume() { + super.onResume() + + rebuildGrid() + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + + rebuildGrid() + } + + private fun rebuildGrid() { + layout.removeAllViews() + val grid = buildFullWidget(this, ClickBehavior.SHARE) + val asView = grid.apply(this, layout) + layout.addView(asView, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT)) + } +} diff --git a/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt new file mode 100644 index 000000000000..c15cabbb0eb6 --- /dev/null +++ b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2021 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.egg.widget + +import android.app.PendingIntent +import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetProvider +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.util.SizeF +import android.widget.RemoteViews + +import com.android.egg.R + +/** + * A homescreen widget to explore the current dynamic system theme. + */ +class PaintChipsWidget : AppWidgetProvider() { + override fun onUpdate( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetIds: IntArray + ) { + for (appWidgetId in appWidgetIds) { + updateAppWidget(context, appWidgetManager, appWidgetId) + } + } + + override fun onAppWidgetOptionsChanged( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int, + newOptions: Bundle? + ) { + // Log.v(TAG, "onAppWidgetOptionsChanged: id=${appWidgetId}") + updateAppWidget(context, appWidgetManager, appWidgetId) + super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions) + } +} + +const val TAG = "PaintChips" + +val SHADE_NUMBERS = intArrayOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000) + +val COLORS_NEUTRAL1 = intArrayOf( + android.R.color.system_neutral1_0, + android.R.color.system_neutral1_10, + android.R.color.system_neutral1_50, + android.R.color.system_neutral1_100, + android.R.color.system_neutral1_200, + android.R.color.system_neutral1_300, + android.R.color.system_neutral1_400, + android.R.color.system_neutral1_500, + android.R.color.system_neutral1_600, + android.R.color.system_neutral1_700, + android.R.color.system_neutral1_800, + android.R.color.system_neutral1_900, + android.R.color.system_neutral1_1000 +) + +val COLORS_NEUTRAL2 = intArrayOf( + android.R.color.system_neutral2_0, + android.R.color.system_neutral2_10, + android.R.color.system_neutral2_50, + android.R.color.system_neutral2_100, + android.R.color.system_neutral2_200, + android.R.color.system_neutral2_300, + android.R.color.system_neutral2_400, + android.R.color.system_neutral2_500, + android.R.color.system_neutral2_600, + android.R.color.system_neutral2_700, + android.R.color.system_neutral2_800, + android.R.color.system_neutral2_900, + android.R.color.system_neutral2_1000 +) + +var COLORS_ACCENT1 = intArrayOf( + android.R.color.system_accent1_0, + android.R.color.system_accent1_10, + android.R.color.system_accent1_50, + android.R.color.system_accent1_100, + android.R.color.system_accent1_200, + android.R.color.system_accent1_300, + android.R.color.system_accent1_400, + android.R.color.system_accent1_500, + android.R.color.system_accent1_600, + android.R.color.system_accent1_700, + android.R.color.system_accent1_800, + android.R.color.system_accent1_900, + android.R.color.system_accent1_1000 +) + +var COLORS_ACCENT2 = intArrayOf( + android.R.color.system_accent2_0, + android.R.color.system_accent2_10, + android.R.color.system_accent2_50, + android.R.color.system_accent2_100, + android.R.color.system_accent2_200, + android.R.color.system_accent2_300, + android.R.color.system_accent2_400, + android.R.color.system_accent2_500, + android.R.color.system_accent2_600, + android.R.color.system_accent2_700, + android.R.color.system_accent2_800, + android.R.color.system_accent2_900, + android.R.color.system_accent2_1000 +) + +var COLORS_ACCENT3 = intArrayOf( + android.R.color.system_accent3_0, + android.R.color.system_accent3_10, + android.R.color.system_accent3_50, + android.R.color.system_accent3_100, + android.R.color.system_accent3_200, + android.R.color.system_accent3_300, + android.R.color.system_accent3_400, + android.R.color.system_accent3_500, + android.R.color.system_accent3_600, + android.R.color.system_accent3_700, + android.R.color.system_accent3_800, + android.R.color.system_accent3_900, + android.R.color.system_accent3_1000 +) + +var COLOR_NAMES = arrayOf( + "N1", "N2", "A1", "A2", "A3" +) + +var COLORS = arrayOf( + COLORS_NEUTRAL1, + COLORS_NEUTRAL2, + COLORS_ACCENT1, + COLORS_ACCENT2, + COLORS_ACCENT3 +) + +internal fun updateAppWidget( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int +) { + // val opts = appWidgetManager.getAppWidgetOptions(appWidgetId) + // Log.v(TAG, "requested sizes=${opts[OPTION_APPWIDGET_SIZES]}") + + val allSizes = mapOf( + SizeF(50f, 50f) + to buildWidget(context, 1, 1, ClickBehavior.LAUNCH), + SizeF(100f, 50f) + to buildWidget(context, 1, 2, ClickBehavior.LAUNCH), + SizeF(150f, 50f) + to buildWidget(context, 1, 3, ClickBehavior.LAUNCH), + SizeF(200f, 50f) + to buildWidget(context, 1, 4, ClickBehavior.LAUNCH), + SizeF(250f, 50f) + to buildWidget(context, 1, 5, ClickBehavior.LAUNCH), + + SizeF(50f, 120f) + to buildWidget(context, 3, 1, ClickBehavior.LAUNCH), + SizeF(100f, 120f) + to buildWidget(context, 3, 2, ClickBehavior.LAUNCH), + SizeF(150f, 120f) + to buildWidget(context, 3, 3, ClickBehavior.LAUNCH), + SizeF(200f, 120f) + to buildWidget(context, 3, 4, ClickBehavior.LAUNCH), + SizeF(250f, 120f) + to buildWidget(context, 3, 5, ClickBehavior.LAUNCH), + + SizeF(50f, 250f) + to buildWidget(context, 5, 1, ClickBehavior.LAUNCH), + SizeF(100f, 250f) + to buildWidget(context, 5, 2, ClickBehavior.LAUNCH), + SizeF(150f, 250f) + to buildWidget(context, 5, 3, ClickBehavior.LAUNCH), + SizeF(200f, 250f) + to buildWidget(context, 5, 4, ClickBehavior.LAUNCH), + SizeF(250f, 250f) + to buildWidget(context, 5, 5, ClickBehavior.LAUNCH), + + SizeF(300f, 300f) + to buildWidget(context, SHADE_NUMBERS.size, COLORS.size, ClickBehavior.LAUNCH) + ) + + // Instruct the widget manager to update the widget + appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(allSizes)) +} + +fun buildFullWidget(context: Context, clickable: ClickBehavior): RemoteViews { + return buildWidget(context, SHADE_NUMBERS.size, COLORS.size, clickable) +} + +fun buildWidget(context: Context, numShades: Int, numColors: Int, clickable: ClickBehavior): + RemoteViews { + val grid = RemoteViews(context.packageName, R.layout.paint_chips_grid) + + // shouldn't be necessary but sometimes the RV instructions get played twice in launcher. + grid.removeAllViews(R.id.paint_grid) + + grid.setInt(R.id.paint_grid, "setRowCount", numShades) + grid.setInt(R.id.paint_grid, "setColumnCount", numColors) + + Log.v(TAG, "building widget: shade rows=$numShades, color columns=$numColors") + + COLORS.forEachIndexed colorLoop@{ i, colorlist -> + when (colorlist) { + COLORS_NEUTRAL1 -> if (numColors < 2) return@colorLoop + COLORS_NEUTRAL2 -> if (numColors < 4) return@colorLoop + COLORS_ACCENT2 -> if (numColors < 3) return@colorLoop + COLORS_ACCENT3 -> if (numColors < 5) return@colorLoop + else -> {} // always do ACCENT1 + } + colorlist.forEachIndexed shadeLoop@{ j, resId -> + when (SHADE_NUMBERS[j]) { + 500 -> {} + 300, 700 -> if (numShades < 3) return@shadeLoop + 100, 900 -> if (numShades < 5) return@shadeLoop + else -> if (numShades < SHADE_NUMBERS.size) return@shadeLoop + } + val cell = RemoteViews(context.packageName, R.layout.paint_chip) + cell.setTextViewText(R.id.chip, "${COLOR_NAMES[i]}-${SHADE_NUMBERS[j]}") + val textColor = if (SHADE_NUMBERS[j] > 500) + colorlist[0] + else colorlist[colorlist.size - 1] + cell.setTextColor(R.id.chip, context.getColor(textColor)) + cell.setColorStateList(R.id.chip, "setBackgroundTintList", resId) + val text = """ + ${COLOR_NAMES[i]}-${SHADE_NUMBERS[j]} (@${ + context.resources.getResourceName(resId) }) + currently: #${ String.format("%06x", context.getColor(resId) and 0xFFFFFF) } + """.trimIndent() + when (clickable) { + ClickBehavior.SHARE -> cell.setOnClickPendingIntent( + R.id.chip, + makeTextSharePendingIntent(context, text) + ) + ClickBehavior.LAUNCH -> cell.setOnClickPendingIntent( + R.id.chip, + makeActivityLaunchPendingIntent(context) + ) + ClickBehavior.NONE -> { } + } + grid.addView(R.id.paint_grid, cell) + } + } + + return grid +} + +enum class ClickBehavior { + NONE, + SHARE, + LAUNCH +} + +fun makeTextSharePendingIntent(context: Context, text: String): PendingIntent { + val shareIntent: Intent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_TEXT, text) + type = "text/plain" + } + + val chooserIntent = Intent.createChooser(shareIntent, null).apply { + identifier = text // incredible quality-of-life improvement, thanks framework team + } + + return PendingIntent.getActivity(context, 0, chooserIntent, + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) +} + +fun makeActivityLaunchPendingIntent(context: Context): PendingIntent { + return PendingIntent.getActivity(context, 0, + Intent().apply { + component = ComponentName(context, PaintChipsActivity::class.java) + action = Intent.ACTION_MAIN + }, + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) +} diff --git a/packages/SettingsLib/lint-baseline.xml b/packages/SettingsLib/lint-baseline.xml index f6d6ca62e78c..d6ea73d1ef3d 100644 --- a/packages/SettingsLib/lint-baseline.xml +++ b/packages/SettingsLib/lint-baseline.xml @@ -892,4 +892,26 @@ column="59"/> </issue> + <issue + id="NewApi" + message="Call requires API level S (current min is 29): `android.os.UserManager#isUserForeground`" + errorLine1=" .getSystemService(UserManager.class).isUserForeground();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java" + line="120" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 31 (current min is 29): `android.os.UserManager#isUserForeground`" + errorLine1=" .getSystemService(UserManager.class).isUserForeground();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java" + line="120" + column="54"/> + </issue> + </issues> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index b3bdf8977227..65992a7048b8 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -444,7 +444,7 @@ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo rimanente: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il telefono potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il tablet potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il dispositivo potrebbe spegnersi a breve"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index b1aee5047fab..7387985cf457 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -309,7 +309,7 @@ <string name="dev_settings_warning_message" msgid="37741686486073668">"Бул орнотуулар өндүрүүчүлөр үчүн гана берилген. Булар түзмөгүңүздүн колдонмолорун бузулушуна же туура эмес иштешине алып келиши мүмкүн."</string> <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Орнотулуучу колдонмону текшерүү"</string> <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT аркылуу орнотулган колдонмолордун коопсуздугу текшерилет."</string> - <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Аталышсыз Bluetooth түзмөктөрү (MAC даректери менен гана) көрсөтүлөт"</string> + <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Аталышсыз Bluetooth түзмөктөрү (MAC даректери менен гана) көрүнөт"</string> <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Алыскы түзмөктөр өтө катуу добуш чыгарып же көзөмөлдөнбөй жатса Bluetooth \"Үндүн абсолюттук деңгээли\" функциясын өчүрөт."</string> <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche функциясынын топтомун иштетет."</string> <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Жакшыртылган туташуу функциясын иштетет."</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index fea9601952e9..2bdd617e9e58 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -443,8 +443,8 @@ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria może się wyczerpać do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało ponad <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało ponad <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Wkrótce telefon może się wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet może się wkrótce wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Urządzenie może się wkrótce wyłączyć"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java index bd9e0d341b2e..7275d6be99ad 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java @@ -18,6 +18,9 @@ package com.android.settingslib.enterprise; import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; +import static com.android.settingslib.enterprise.ActionDisabledLearnMoreButtonLauncher.DEFAULT_RESOLVE_ACTIVITY_CHECKER; +import static com.android.settingslib.enterprise.ManagedDeviceActionDisabledByAdminController.DEFAULT_FOREGROUND_USER_CHECKER; + import android.app.admin.DevicePolicyManager; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; @@ -43,7 +46,11 @@ public final class ActionDisabledByAdminControllerFactory { } else if (isFinancedDevice(context)) { return new FinancedDeviceActionDisabledByAdminController(stringProvider); } else { - return new ManagedDeviceActionDisabledByAdminController(stringProvider, userHandle); + return new ManagedDeviceActionDisabledByAdminController( + stringProvider, + userHandle, + DEFAULT_FOREGROUND_USER_CHECKER, + DEFAULT_RESOLVE_ACTIVITY_CHECKER); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java index 411487976fe5..f9d3aaf6b383 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java @@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.UserHandle; import android.os.UserManager; @@ -34,6 +35,17 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; */ public abstract class ActionDisabledLearnMoreButtonLauncher { + public static ResolveActivityChecker DEFAULT_RESOLVE_ACTIVITY_CHECKER = + (packageManager, url, userHandle) -> packageManager.resolveActivityAsUser( + createLearnMoreIntent(url), + PackageManager.MATCH_DEFAULT_ONLY, + userHandle.getIdentifier()) != null; + + interface ResolveActivityChecker { + boolean canResolveActivityAsUser( + PackageManager packageManager, String url, UserHandle userHandle); + } + /** * Sets up a "learn more" button which shows a screen with device policy settings */ @@ -111,6 +123,14 @@ public abstract class ActionDisabledLearnMoreButtonLauncher { finishSelf(); } + protected final boolean canLaunchHelpPage( + PackageManager packageManager, + String url, + UserHandle userHandle, + ResolveActivityChecker resolveActivityChecker) { + return resolveActivityChecker.canResolveActivityAsUser(packageManager, url, userHandle); + } + private void showAdminPolicies(Context context, EnforcedAdmin enforcedAdmin) { if (enforcedAdmin.component != null) { launchShowAdminPolicies(context, enforcedAdmin.user, enforcedAdmin.component); diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java index 1472980efd4e..e0339dacf5ac 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java @@ -64,9 +64,9 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled return (dialog, which) -> { Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component); final Intent intent = new Intent(ACTION_LEARN_MORE) - .setComponent(enforcedAdmin.component) .putExtra(EXTRA_SETTING_KEY, EXTRA_SETTING_VALUE) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .setPackage(enforcedAdmin.component.getPackageName()); context.startActivity(intent); }; } diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java index 93e811d6baaa..c2034f89e18a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java @@ -20,13 +20,14 @@ import static java.util.Objects.requireNonNull; import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.content.pm.PackageManager; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import androidx.annotation.Nullable; -import java.util.Objects; +import com.android.settingslib.enterprise.ActionDisabledLearnMoreButtonLauncher.ResolveActivityChecker; /** @@ -35,17 +36,37 @@ import java.util.Objects; final class ManagedDeviceActionDisabledByAdminController extends BaseActionDisabledByAdminController { - private final UserHandle mUserHandle; + interface ForegroundUserChecker { + boolean isUserForeground(Context context, UserHandle userHandle); + } + + public final static ForegroundUserChecker DEFAULT_FOREGROUND_USER_CHECKER = + ManagedDeviceActionDisabledByAdminController::isUserForeground; + + /** + * The {@link UserHandle} which is preferred for launching the web help page in + * <p>If not able to launch the web help page in this user, the current user will be used as + * fallback instead. If the current user cannot open it either, the admin policies page will + * be used instead. + */ + private final UserHandle mPreferredUserHandle; + + private final ForegroundUserChecker mForegroundUserChecker; + private final ResolveActivityChecker mResolveActivityChecker; /** * Constructs a {@link ManagedDeviceActionDisabledByAdminController} - * @param userHandle - user on which to launch the help web page, if necessary + * @param preferredUserHandle - user on which to launch the help web page, if necessary */ ManagedDeviceActionDisabledByAdminController( DeviceAdminStringProvider stringProvider, - UserHandle userHandle) { + UserHandle preferredUserHandle, + ForegroundUserChecker foregroundUserChecker, + ResolveActivityChecker resolveActivityChecker) { super(stringProvider); - mUserHandle = requireNonNull(userHandle); + mPreferredUserHandle = requireNonNull(preferredUserHandle); + mForegroundUserChecker = requireNonNull(foregroundUserChecker); + mResolveActivityChecker = requireNonNull(resolveActivityChecker); } @Override @@ -53,14 +74,52 @@ final class ManagedDeviceActionDisabledByAdminController assertInitialized(); String url = mStringProvider.getLearnMoreHelpPageUrl(); - if (TextUtils.isEmpty(url)) { + + if (!TextUtils.isEmpty(url) + && canLaunchHelpPageInPreferredOrCurrentUser(context, url, mPreferredUserHandle)) { + setupLearnMoreButtonToLaunchHelpPage(context, url, mPreferredUserHandle); + } else { mLauncher.setupLearnMoreButtonToShowAdminPolicies(context, mEnforcementAdminUserId, mEnforcedAdmin); - } else { - mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, mUserHandle); } } + private boolean canLaunchHelpPageInPreferredOrCurrentUser( + Context context, String url, UserHandle preferredUserHandle) { + PackageManager packageManager = context.getPackageManager(); + if (mLauncher.canLaunchHelpPage( + packageManager, url, preferredUserHandle, mResolveActivityChecker) + && mForegroundUserChecker.isUserForeground(context, preferredUserHandle)) { + return true; + } + return mLauncher.canLaunchHelpPage( + packageManager, url, context.getUser(), mResolveActivityChecker); + } + + /** + * Sets up the "Learn more" button to launch the web help page in the {@code + * preferredUserHandle} user. If not possible to launch it there, it sets up the button to + * launch it in the current user instead. + */ + private void setupLearnMoreButtonToLaunchHelpPage( + Context context, String url, UserHandle preferredUserHandle) { + PackageManager packageManager = context.getPackageManager(); + if (mLauncher.canLaunchHelpPage( + packageManager, url, preferredUserHandle, mResolveActivityChecker) + && mForegroundUserChecker.isUserForeground(context, preferredUserHandle)) { + mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, preferredUserHandle); + } + if (mLauncher.canLaunchHelpPage( + packageManager, url, context.getUser(), mResolveActivityChecker)) { + mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, context.getUser()); + } + } + + private static boolean isUserForeground(Context context, UserHandle userHandle) { + return context.createContextAsUser(userHandle, /* flags= */ 0) + .getSystemService(UserManager.class).isUserForeground(); + } + @Override public String getAdminSupportTitle(@Nullable String restriction) { if (restriction == null) { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java index d9be4f336797..509e12d241dd 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java @@ -30,6 +30,8 @@ import static com.google.common.truth.Truth.assertThat; import android.app.Activity; import android.content.Context; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; import android.os.UserManager; import androidx.test.core.app.ApplicationProvider; @@ -45,9 +47,11 @@ import org.robolectric.android.controller.ActivityController; @RunWith(RobolectricTestRunner.class) public class ManagedDeviceActionDisabledByAdminControllerTest { + private static UserHandle MANAGED_USER = UserHandle.of(123); private static final String RESTRICTION = UserManager.DISALLOW_ADJUST_VOLUME; private static final String EMPTY_URL = ""; private static final String SUPPORT_TITLE_FOR_RESTRICTION = DISALLOW_ADJUST_VOLUME_TITLE; + public static final ResolveInfo TEST_RESULT_INFO = new ResolveInfo(); private final Context mContext = ApplicationProvider.getApplicationContext(); private final Activity mActivity = ActivityController.of(new Activity()).get(); @@ -60,8 +64,21 @@ public class ManagedDeviceActionDisabledByAdminControllerTest { } @Test - public void setupLearnMoreButton_validUrl_negativeButtonSet() { - ManagedDeviceActionDisabledByAdminController controller = createController(URL); + public void setupLearnMoreButton_noUrl_negativeButtonSet() { + ManagedDeviceActionDisabledByAdminController controller = createController(EMPTY_URL); + + controller.setupLearnMoreButton(mContext); + + mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES); + } + + @Test + public void setupLearnMoreButton_validUrl_foregroundUser_launchesHelpPage() { + ManagedDeviceActionDisabledByAdminController controller = createController( + URL, + /* isUserForeground= */ true, + /* preferredUserHandle= */ MANAGED_USER, + /* userContainingBrowser= */ MANAGED_USER); controller.setupLearnMoreButton(mContext); @@ -69,8 +86,38 @@ public class ManagedDeviceActionDisabledByAdminControllerTest { } @Test - public void setupLearnMoreButton_noUrl_negativeButtonSet() { - ManagedDeviceActionDisabledByAdminController controller = createController(EMPTY_URL); + public void setupLearnMoreButton_validUrl_browserInPreferredUser_notForeground_showsAdminPolicies() { + ManagedDeviceActionDisabledByAdminController controller = createController( + URL, + /* isUserForeground= */ false, + /* preferredUserHandle= */ MANAGED_USER, + /* userContainingBrowser= */ MANAGED_USER); + + controller.setupLearnMoreButton(mContext); + + mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES); + } + + @Test + public void setupLearnMoreButton_validUrl_browserInCurrentUser_launchesHelpPage() { + ManagedDeviceActionDisabledByAdminController controller = createController( + URL, + /* isUserForeground= */ false, + /* preferredUserHandle= */ MANAGED_USER, + /* userContainingBrowser= */ mContext.getUser()); + + controller.setupLearnMoreButton(mContext); + + mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_LAUNCH_HELP_PAGE); + } + + @Test + public void setupLearnMoreButton_validUrl_browserNotOnAnyUser_showsAdminPolicies() { + ManagedDeviceActionDisabledByAdminController controller = createController( + URL, + /* isUserForeground= */ false, + /* preferredUserHandle= */ MANAGED_USER, + /* userContainingBrowser= */ null); controller.setupLearnMoreButton(mContext); @@ -110,13 +157,33 @@ public class ManagedDeviceActionDisabledByAdminControllerTest { } private ManagedDeviceActionDisabledByAdminController createController() { - return createController(/* url= */ null); + return createController( + /* url= */ null, + /* foregroundUserChecker= */ true, + mContext.getUser(), + /* userContainingBrowser= */ null); } private ManagedDeviceActionDisabledByAdminController createController(String url) { + return createController( + url, + /* foregroundUserChecker= */ true, + mContext.getUser(), + /* userContainingBrowser= */ null); + } + + private ManagedDeviceActionDisabledByAdminController createController( + String url, + boolean isUserForeground, + UserHandle preferredUserHandle, + UserHandle userContainingBrowser) { ManagedDeviceActionDisabledByAdminController controller = new ManagedDeviceActionDisabledByAdminController( - new FakeDeviceAdminStringProvider(url), mContext.getUser()); + new FakeDeviceAdminStringProvider(url), + preferredUserHandle, + /* foregroundUserChecker= */ (context, userHandle) -> isUserForeground, + /* resolveActivityChecker= */ (packageManager, __, userHandle) -> + userHandle.equals(userContainingBrowser)); controller.initialize(mTestUtils.createLearnMoreButtonLauncher()); controller.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID); return controller; diff --git a/packages/SystemUI/res/drawable-nodpi/android_12.xml b/packages/SystemUI/res/drawable-nodpi/android_12.xml new file mode 100644 index 000000000000..bdeeced2d290 --- /dev/null +++ b/packages/SystemUI/res/drawable-nodpi/android_12.xml @@ -0,0 +1,37 @@ +<!-- +Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2 (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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48dp" + android:height="48dp" + android:viewportWidth="48" + android:viewportHeight="48"> + <group> + <clip-path + android:pathData="M14,14h21v20h-21z"/> + <path + android:pathData="M15,15C15.7956,15 16.5587,15.3161 17.1213,15.8787C17.6839,16.4413 18,17.2044 18,18V33" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#ffffff" + android:strokeLineCap="round"/> + <path + android:pathData="M34,33H22V30C22,28.4087 22.6321,26.8826 23.7574,25.7574C24.8826,24.6321 26.4087,24 28,24H31C31.7956,24 32.5587,23.6839 33.1213,23.1213C33.6839,22.5587 34,21.7957 34,21C34.009,19.5779 33.5126,18.1989 32.5993,17.1088C31.686,16.0188 30.4153,15.2885 29.0136,15.0483C27.612,14.8081 26.1706,15.0735 24.9464,15.7973C23.7223,16.5211 22.795,17.6561 22.33,19C22.2199,19.3261 22.1363,19.6605 22.08,20" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#ffffff" + android:strokeLineCap="round"/> + </group> +</vector> diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml index 7f8d4fa8833f..997249632709 100644 --- a/packages/SystemUI/res/drawable-nodpi/icon.xml +++ b/packages/SystemUI/res/drawable-nodpi/icon.xml @@ -15,5 +15,5 @@ Copyright (C) 2018 The Android Open Source Project --> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@drawable/icon_bg"/> - <foreground android:drawable="@drawable/android_11_dial"/> + <foreground android:drawable="@drawable/android_12"/> </adaptive-icon> diff --git a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml index 31b2a7f9a333..ff7cbae16ab2 100644 --- a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml +++ b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml @@ -14,5 +14,5 @@ Copyright (C) 2018 The Android Open Source Project limitations under the License. --> <color xmlns:android="http://schemas.android.com/apk/res/android" - android:color="#073042" /> + android:color="@android:color/system_accent1_500" /> diff --git a/packages/SystemUI/res/drawable/fingerprint_bg.xml b/packages/SystemUI/res/drawable/fingerprint_bg.xml index 2b0ab6f9a8d2..558ec08b2ceb 100644 --- a/packages/SystemUI/res/drawable/fingerprint_bg.xml +++ b/packages/SystemUI/res/drawable/fingerprint_bg.xml @@ -14,10 +14,11 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="oval"> <solid - android:color="?android:attr/colorBackground"/> + android:color="?androidprv:attr/colorSurface"/> <size android:width="64dp" diff --git a/packages/SystemUI/res/drawable/ic_unlock.xml b/packages/SystemUI/res/drawable/ic_unlock.xml new file mode 100644 index 000000000000..c3b34699e8e2 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_unlock.xml @@ -0,0 +1,42 @@ +<!-- + Copyright (C) 2021 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. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46"> + <group android:translateX="8.625" android:translateY="13.625"> + <path + android:strokeColor="#FF000000" + android:strokeLineCap="round" + android:strokeLineJoin="round" + android:strokeWidth="2.5" + android:pathData="M4.75 15 C4.75,15 23.25,15 23.25,15 C24.35,15 25.25,15.9 25.25,17 C25.25,17 25.25,33 25.25,33 C25.25,34.1 24.35,35 23.25,35 C23.25,35 4.75,35 4.75,35 C3.65,35 2.75,34.1 2.75,33 C2.75,33 2.75,17 2.75,17 C2.75,15.9 3.65,15 4.75,15c " /> + </group> + <group android:translateX="14" android:translateY="13.5"> + <path + android:strokeColor="#FF000000" + android:strokeLineCap="round" + android:strokeLineJoin="round" + android:strokeWidth="2.5" + android:pathData="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " /> + </group> + <group android:translateX="20" android:translateY="35.75"> + <path + android:fillColor="#FF000000" + android:fillAlpha="1" + android:fillType="nonZero" + android:pathData=" M2.75 5.25 C4.13,5.25 5.25,4.13 5.25,2.75 C5.25,1.37 4.13,0.25 2.75,0.25 C1.37,0.25 0.25,1.37 0.25,2.75 C0.25,4.13 1.37,5.25 2.75,5.25c " /> + </group> +</vector> diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml index 2789ed125b09..eb7638233efd 100644 --- a/packages/SystemUI/res/layout/keyguard_status_bar.xml +++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml @@ -30,6 +30,7 @@ android:id="@+id/status_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" + android:paddingEnd="@dimen/system_icons_keyguard_padding_end" android:paddingTop="@dimen/status_bar_padding_top" android:layout_alignParentEnd="true" android:gravity="center_vertical|end" > @@ -38,12 +39,10 @@ android:layout_height="match_parent" android:layout_weight="1" android:layout_marginStart="@dimen/system_icons_super_container_margin_start" - android:gravity="center_vertical|end" - android:paddingEnd="@dimen/system_icons_keyguard_padding_end" > + android:gravity="center_vertical|end"> <include layout="@layout/system_icons" /> </FrameLayout> - <ImageView android:id="@+id/multi_user_avatar" android:layout_width="@dimen/multi_user_avatar_keyguard_size" android:layout_height="@dimen/multi_user_avatar_keyguard_size" diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 1a912023e33c..b0f1f487b260 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -55,9 +55,23 @@ android:id="@+id/lock_icon_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:padding="48px" - android:layout_gravity="center" - android:scaleType="centerCrop"/> + android:layout_gravity="center"> + <!-- Background protection --> + <ImageView + android:id="@+id/lock_icon_bg" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/fingerprint_bg" + android:visibility="invisible"/> + + <ImageView + android:id="@+id/lock_icon" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="48px" + android:layout_gravity="center" + android:scaleType="centerCrop"/> + </com.android.keyguard.LockIconView> <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view.xml b/packages/SystemUI/res/layout/udfps_keyguard_view.xml index 8834ac040b54..1851790673e3 100644 --- a/packages/SystemUI/res/layout/udfps_keyguard_view.xml +++ b/packages/SystemUI/res/layout/udfps_keyguard_view.xml @@ -26,8 +26,7 @@ android:id="@+id/udfps_keyguard_fp_bg" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@drawable/fingerprint_bg" - android:visibility="gone"/> + android:src="@drawable/fingerprint_bg"/> <!-- Fingerprint --> <!-- AOD dashed fingerprint icon with moving dashes --> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 3506057bd5ac..5a4a8ea20891 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tik weer om oop te maak"</string> <string name="tap_again" msgid="1315420114387908655">"Tik weer"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Druk om oop te maak"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string> diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml index 5420779a98ca..c20d01e885f2 100644 --- a/packages/SystemUI/res/values-af/strings_tv.xml +++ b/packages/SystemUI/res/values-af/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Kennisgewings"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Geen kennisgewings nie"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofoon neem tans op"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera neem tans op"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera en mikrofoon neem tans op"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofoon het opname gestop"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera het opname gestop"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera en mikrofoon het opname gestop"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 74009bf50bbc..3a3938fc16d3 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ለመክፈት ዳግም መታ ያድርጉ"</string> <string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ለመክፈት ይጫኑ"</string> <string name="keyguard_retry" msgid="886802522584053523">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCን ለመጠቀም ይክፈቱ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ይህ መሣሪያ የድርጅትዎ ነው"</string> diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml index ede0b782c064..39429e4a20ac 100644 --- a/packages/SystemUI/res/values-am/strings_tv.xml +++ b/packages/SystemUI/res/values-am/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ማሳወቂያዎች"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ምንም ማሳወቂያዎች የሉም"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ማይክሮፎን እየቀዳ ነው"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ካሜራ እየቀረጸ ነው"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ካሜራ እየቀረጸ እና ማይክሮፎን እየቀዳ ነው"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ማይክሮፎን መቅዳት አቁሟል"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ካሜራ መቅረጽ አቁሟል"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ካሜራ መቅረጽ እና ማይክሮፎን መቅዳት አቁመዋል"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 993ee39ab808..72279a6ed89d 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -460,6 +460,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"انقر مرة أخرى للفتح"</string> <string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"اضغط لفتح الجهاز."</string> <string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"افتح قفل الشاشة لاستخدام تقنية NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string> diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml index f6c4aefec4f1..13f23f019f1b 100644 --- a/packages/SystemUI/res/values-ar/strings_tv.xml +++ b/packages/SystemUI/res/values-ar/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"عبر <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"الإشعارات"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ما من إشعارات"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"جارٍ التسجيل بالميكرفون"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"جارٍ التسجيل بالكاميرا"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"جارٍ التسجيل بالكاميرا والميكروفون"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"توقف التسجيل بالميكرفون."</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"توقف التسجيل بالكاميرا."</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"توقف التسجيل بالكاميرا والميكروفون."</string> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 20023c0b36d0..7fe06e3bfe2b 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"খুলিবলৈ পুনৰাই টিপক"</string> <string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"খুলিবলৈ টিপক"</string> <string name="keyguard_retry" msgid="886802522584053523">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string> diff --git a/packages/SystemUI/res/values-as/strings_tv.xml b/packages/SystemUI/res/values-as/strings_tv.xml index 6ceee805cdfc..733e2e6c72e7 100644 --- a/packages/SystemUI/res/values-as/strings_tv.xml +++ b/packages/SystemUI/res/values-as/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"জাননী"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"কোনো জাননী নাই"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰি আছে"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"কেমেৰাটোৱে ৰেক’ৰ্ড কৰি আছে"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"কেমেৰা আৰু মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰি আছে"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"কেমেৰাটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"কেমেৰা আৰু মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 71f90fd519aa..0b97347d70f1 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Açmaq üçün yenidən tıklayın"</string> <string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Açmaq üçün basın"</string> <string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string> diff --git a/packages/SystemUI/res/values-az/strings_tv.xml b/packages/SystemUI/res/values-az/strings_tv.xml index d141ad6d3fd1..cd8b46c7a901 100644 --- a/packages/SystemUI/res/values-az/strings_tv.xml +++ b/packages/SystemUI/res/values-az/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Bildirişlər"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Bildiriş yoxdur"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon yazır"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera yazır"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera və mikrofon yazır"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon yazmağı dayandırıb"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera yazmağı dayandırıb"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera və mikrofon yazmağı dayandırıb"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 7402594b3c59..2aff0a34271c 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string> <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da biste otvorili"</string> <string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml index 04a7e813765b..31a37dbd54e3 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obaveštenja"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obaveštenja"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Snimanje mikrofonom je zaustavljeno"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Snimanje kamerom je zaustavljeno"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Snimanje kamerom i mikrofonom je zaustavljeno"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 7688e06dba25..ac37b8e8451e 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Дакраніцеся яшчэ раз, каб адкрыць"</string> <string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Націсніце, каб адкрыць"</string> <string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string> diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml index 5aa771f0638c..410c1202c9ed 100644 --- a/packages/SystemUI/res/values-be/strings_tv.xml +++ b/packages/SystemUI/res/values-be/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Праз <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Апавяшчэнні"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Апавяшчэнняў няма"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Ідзе запіс з выкарыстаннем мікрафона"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Ідзе запіс з выкарыстаннем камеры"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Ідзе запіс з выкарыстаннем камеры і мікрафона"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Запіс з выкарыстаннем мікрафона спынены"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Запіс з выкарыстаннем камеры спынены"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Запіс з выкарыстаннем камеры і мікрафона спынены"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 386fbd6a8520..73724a8ba617 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Докоснете отново, за да отворите"</string> <string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Натиснете за отваряне"</string> <string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string> diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml index 49bf014d2fa6..981ab95c80ce 100644 --- a/packages/SystemUI/res/values-bg/strings_tv.xml +++ b/packages/SystemUI/res/values-bg/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Известия"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Няма известия"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофонът записва"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камерата записва"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камерата и микрофонът записват"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофонът спря да записва"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камерата спря да записва"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камерата и микрофонът спряха да записват"</string> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index d26912604bb5..a70fa8d18b25 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"খোলার জন্য আবার আলতো চাপুন"</string> <string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"আনলক করার জন্য প্রেস করুন"</string> <string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string> diff --git a/packages/SystemUI/res/values-bn/strings_tv.xml b/packages/SystemUI/res/values-bn/strings_tv.xml index 5a9b45612096..5d252b17aea6 100644 --- a/packages/SystemUI/res/values-bn/strings_tv.xml +++ b/packages/SystemUI/res/values-bn/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"বিজ্ঞপ্তি"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"কোনও বিজ্ঞপ্তি নেই"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"মাইক্রোফোনে রেকর্ড করা হচ্ছে"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ক্যামেরায় রেকর্ড করা হচ্ছে"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ক্যামেরা ও মাইক্রোফোনে রেকর্ড করা হচ্ছে"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"মাইক্রোফোনে রেকর্ড করা বন্ধ হয়ে গেছে"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ক্যামেরায় রেকর্ড করা বন্ধ হয়ে গেছে"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ক্যামেরা ও মাইক্রোফোনে রেকর্ড করা বন্ধ হয়ে গেছে"</string> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 2857eccd0633..afc21b5a605c 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da otvorite"</string> <string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da otvorite"</string> <string name="keyguard_retry" msgid="886802522584053523">"Prevucite prema gore da pokušate ponovo"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da koristite NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string> diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml index 92c5e2a0ebea..341c12508236 100644 --- a/packages/SystemUI/res/values-bs/strings_tv.xml +++ b/packages/SystemUI/res/values-bs/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Putem: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obavještenja"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obavještenja"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon je prestao snimati"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera je prestala snimati"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera i mikrofon su prestali snimati"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index c25dca5c91e6..e9da15559214 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Torna a tocar per obrir-la."</string> <string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Prem per obrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string> diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml index dac4a1a0d0d9..6a28c837f7e3 100644 --- a/packages/SystemUI/res/values-ca/strings_tv.xml +++ b/packages/SystemUI/res/values-ca/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Mitjançant <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificacions"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Cap notificació"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"El micròfon està gravant"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"La càmera està gravant"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La càmera i el micròfon estan gravant"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micròfon ha deixat de gravar"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La càmera ha deixat de gravar"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La càmera i el micròfon han deixat de gravar"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 5fed1b3e3f30..3463586f3c5e 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Oznámení otevřete opětovným klepnutím"</string> <string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Stisknutím otevřete"</string> <string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string> diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml index e9f4a10eaeb1..115c875f8194 100644 --- a/packages/SystemUI/res/values-cs/strings_tv.xml +++ b/packages/SystemUI/res/values-cs/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Přes <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Oznámení"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Žádná oznámení"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon nahrává"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nahrává"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera a mikrofon nahrávají"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon přestal nahrávat"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera přestala nahrávat"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera a mikrofon přestaly nahrávat"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index facedf0ff039..8367077445ff 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tryk igen for at åbne"</string> <string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tryk for at åbne"</string> <string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string> diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml index 953477634f7c..af489467df89 100644 --- a/packages/SystemUI/res/values-da/strings_tv.xml +++ b/packages/SystemUI/res/values-da/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifikationer"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ingen notifikationer"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen optager"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameraet optager"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameraet og mikrofonen optager"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen er stoppet med at optage"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameraet er stoppet med at optage"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameraet og mikrofonen er stoppet med at optage"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 5d10eb4b25b9..f2cb79a300ff 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Erneut tippen, um Benachrichtigung zu öffnen"</string> <string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Zum Öffnen klicken"</string> <string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string> diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml index ec162ef0936a..e8e8dcd2226e 100644 --- a/packages/SystemUI/res/values-de/strings_tv.xml +++ b/packages/SystemUI/res/values-de/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Über <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Benachrichtigungen"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Keine Benachrichtigungen"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon nimmt auf"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nimmt auf"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera und Mikrofon nehmen auf"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Aufnahme des Mikrofons gestoppt"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Aufnahme der Kamera gestoppt"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Aufnahme von Kamera und Mikrofon gestoppt"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index cfda46f64eda..ef7771df0295 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Πατήστε ξανά για να ανοίξετε"</string> <string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Πατήστε για άνοιγμα"</string> <string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string> diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml index 175c402ab8b3..01def2b2418b 100644 --- a/packages/SystemUI/res/values-el/strings_tv.xml +++ b/packages/SystemUI/res/values-el/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Μέσω <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Ειδοποιήσεις"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Δεν υπάρχουν ειδοποιήσεις."</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Πραγματοποιείται εγγραφή από το μικρόφωνο"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Πραγματοποιείται εγγραφή από την κάμερα"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Πραγματοποιείται εγγραφή από την κάμερα και το μικρόφωνο"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Η εγγραφή από το μικρόφωνο διακόπηκε"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Η εγγραφή από την κάμερα διακόπηκε"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Η εγγραφή από την κάμερα και το μικρόφωνο διακόπηκε"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 9af2d89ce21d..905beaedc642 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string> <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 398420a68f5c..51ed681f4676 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string> <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 9af2d89ce21d..905beaedc642 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string> <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 9af2d89ce21d..905beaedc642 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string> <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index b21102657db8..8cd587e04166 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string> <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organization"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 4520ed33f784..c1323ce57994 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Presiona de nuevo para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Presiona para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml index 680e7cc74885..f2f06015e366 100644 --- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml +++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificaciones"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No hay notificaciones"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"El micrófono está grabando"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"La cámara está grabando"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La cámara y el micrófono están grabando"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micrófono dejó de grabar"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La cámara dejó de grabar"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La cámara y el micrófono dejaron de grabar"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index c5096e9c1a35..bcac5cb4e008 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toca de nuevo para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pulsa para abrirlo"</string> <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml index 16154a453321..cc78cf21663d 100644 --- a/packages/SystemUI/res/values-es/strings_tv.xml +++ b/packages/SystemUI/res/values-es/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificaciones"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Sin notificaciones"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"El micrófono está grabando"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"La cámara está grabando"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La cámara y el micrófono están grabando"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micrófono ha dejado de grabar"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La cámara ha dejado de grabar"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La cámara y el micrófono han dejado de grabar"</string> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index ee7c76039408..83fd5e559023 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Avamiseks puudutage uuesti"</string> <string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Avamiseks vajutage"</string> <string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string> diff --git a/packages/SystemUI/res/values-et/strings_tv.xml b/packages/SystemUI/res/values-et/strings_tv.xml index 373202004093..6f020c60d9a4 100644 --- a/packages/SystemUI/res/values-et/strings_tv.xml +++ b/packages/SystemUI/res/values-et/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Teenuse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Märguanded"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Märguandeid pole"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon salvestab"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kaamera salvestab"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kaamera ja mikrofon salvestavad"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon peatas salvestamise"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kaamera peatas salvestamise"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kaamera ja mikrofon peatasid salvestamise"</string> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 0972c26b9ed1..7a36b9b657c1 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Irekitzeko, ukitu berriro"</string> <string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Sakatu irekitzeko"</string> <string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFC erabiltzeko"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string> diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml index 524165e6ac87..c9c30c726c7f 100644 --- a/packages/SystemUI/res/values-eu/strings_tv.xml +++ b/packages/SystemUI/res/values-eu/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> bidez"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Jakinarazpenak"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ez dago jakinarazpenik"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonoa grabatzen ari da"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera grabatzen ari da"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera eta mikrofonoa grabatzen ari dira"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonoak grabatzeari utzi dio"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamerak grabatzeari utzi dio"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamerak eta mikrofonoak grabatzeari utzi diote"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 2899e173e11c..f8e1378c4768 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string> <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند بهبالا بکشید"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"برای باز کردن فشار دهید"</string> <string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند بهبالا بکشید"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"برای استفاده از NFC، قفل را باز کنید"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string> diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml index 803875528c90..3ba9b4e5ca2c 100644 --- a/packages/SystemUI/res/values-fa/strings_tv.xml +++ b/packages/SystemUI/res/values-fa/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"اعلانها"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"اعلانی ندارید"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"میکروفون درحال ضبط کردن است"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"دوربین درحال ضبط کردن است"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"دوربین و میکروفون درحال ضبط کردن هستند"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ضبط میکروفون متوقف شد"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ضبط دوربین متوقف شد"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ضبط دوربین و میکروفون متوقف شد"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index dc49957d6773..d4449f1b57f5 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Avaa napauttamalla uudelleen"</string> <string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Avaa painamalla"</string> <string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus, jotta voit käyttää NFC:tä"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string> diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml index 17797d75e944..63128371c0f0 100644 --- a/packages/SystemUI/res/values-fi/strings_tv.xml +++ b/packages/SystemUI/res/values-fi/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Palvelun <xliff:g id="VPN_APP">%1$s</xliff:g> kautta"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Ilmoitukset"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ei ilmoituksia"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofoni tallentaa"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera kuvaa"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ja mikrofoni tallentavat"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofoni lopetti tallentamisen"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera lopetti kuvaamisen"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ja mikrofoni lopettivat tallentamisen"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 83c0ef4da28d..c1dd1046dc6f 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Touchez à nouveau pour ouvrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Appuyez pour ouvrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml index 7f45411c939c..0925abeb5a00 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Par <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Aucune notification"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Le microphone enregistre"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"L\'appareil photo enregistre"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"L\'appareil photo et le microphone enregistrent"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Le microphone a arrêté l\'enregistrement"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"L\'appareil photo a arrêté l\'enregistrement"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"L\'appareil photo et le microphone ont arrêté l\'enregistrement"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index bb3183e3761b..c06c62f004a9 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Appuyer à nouveau pour ouvrir"</string> <string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Appuyez pour ouvrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string> diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml index 99bab800abe5..3a33aad577e3 100644 --- a/packages/SystemUI/res/values-fr/strings_tv.xml +++ b/packages/SystemUI/res/values-fr/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Aucune notification"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Le micro enregistre…"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"La caméra enregistre…"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La caméra et le micro enregistrent…"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Le micro a arrêté l\'enregistrement"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La caméra a arrêté l\'enregistrement"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La caméra et le micro ont arrêté l\'enregistrement"</string> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index d8fe4b8249d1..f70dd3cbe4c4 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toca de novo para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Preme para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización."</string> diff --git a/packages/SystemUI/res/values-gl/strings_tv.xml b/packages/SystemUI/res/values-gl/strings_tv.xml index 0d35c4dcfaca..679c21da5032 100644 --- a/packages/SystemUI/res/values-gl/strings_tv.xml +++ b/packages/SystemUI/res/values-gl/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificacións"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Non hai notificacións"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"O micrófono está gravando"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"A cámara está gravando"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A cámara e o micrófono están gravando"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O micrófono deixou de gravar"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A cámara deixou de gravar"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A cámara e o micrófono deixaron de gravar"</string> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 553924abda3b..fe16c9593e9f 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ખોલવા માટે ફરીથી ટૅપ કરો"</string> <string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"અનલૉક કરવા માટે દબાવો"</string> <string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string> diff --git a/packages/SystemUI/res/values-gu/strings_tv.xml b/packages/SystemUI/res/values-gu/strings_tv.xml index c2c8ad647b7e..e22650386327 100644 --- a/packages/SystemUI/res/values-gu/strings_tv.xml +++ b/packages/SystemUI/res/values-gu/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"નોટિફિકેશન"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"કોઈ નોટિફિકેશન નથી"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"માઇક્રોફોનનું રેકોર્ડિંગ ચાલુ છે"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"કૅમેરાનું રેકોર્ડિંગ ચાલુ છે"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"કૅમેરા અને માઇક્રોફોનનું રેકોર્ડિંગ ચાલુ છે"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"માઇક્રોફોનનું રેકોર્ડિંગ બંધ થઈ ગયું"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"કૅમેરાનું રેકોર્ડિંગ બંધ થઈ ગયું"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"કૅમેરા અને માઇક્રોફોનનું રેકોર્ડિંગ બંધ થઈ ગયું"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index ac4a9035f3d3..464a7976b80c 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"खोलने के लिए फिर से टैप करें"</string> <string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"अनलॉक करने के लिए दबाएं"</string> <string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string> diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml index eb8f1504c9d9..cc9a56251098 100644 --- a/packages/SystemUI/res/values-hi/strings_tv.xml +++ b/packages/SystemUI/res/values-hi/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचनाएं"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"कोई सूचना नहीं है"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"माइक्रोफ़ोन रिकॉर्ड कर रहा है"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"कैमरा रिकॉर्ड कर रहा है"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"कैमरा और माइक्रोफ़ोन रिकॉर्ड कर रहे हैं"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"माइक्रोफ़ोन ने रिकॉर्ड करना बंद कर दिया है"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"कैमरे ने रिकॉर्ड करना बंद कर दिया है"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"कैमरे और माइक्रोफ़ोन ने रिकॉर्ड करना बंद कर दिया है"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 571ca2427e35..118927a0d411 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite opet za otvaranje"</string> <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da biste otvorili"</string> <string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string> diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml index 241195bade80..633847c8d3ca 100644 --- a/packages/SystemUI/res/values-hr/strings_tv.xml +++ b/packages/SystemUI/res/values-hr/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Putem mreže <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obavijesti"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obavijesti"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon je prestao snimati"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera je prestala snimati"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera i mikrofon prestali su snimati"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 9a7ca9d6d3a5..6ee8db5770ff 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Koppintson ismét a megnyitáshoz"</string> <string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"A megnyitáshoz nyomja meg"</string> <string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string> diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml index e825584d42c7..97c375aff4bd 100644 --- a/packages/SystemUI/res/values-hu/strings_tv.xml +++ b/packages/SystemUI/res/values-hu/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Ezzel: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Értesítések"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nincs értesítés"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"A mikrofon felvételt készít…"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"A kamera felvételt készít…"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A kamera és a mikrofon felvételt készít…"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"A mikrofon befejezte a felvételkészítést"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A kamera befejezte a felvételkészítést"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A kamera és a mikrofon befejezte a felvételkészítést"</string> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 74ab34df000b..982527716a4d 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Կրկին հպեք՝ բացելու համար"</string> <string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Սեղմեք՝ բացելու համար"</string> <string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string> diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml index 0fab090af8a4..3f46b901d150 100644 --- a/packages/SystemUI/res/values-hy/strings_tv.xml +++ b/packages/SystemUI/res/values-hy/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Ծանուցումներ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ծանուցումներ չկան"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Խոսափողը ձայնագրում է"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Տեսախցիկը տեսագրում է"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Տեսախցիկն ու խոսափողը տեսաձայնագրում են"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Խոսափողն այլևս չի ձայնագրում"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Տեսախցիկն այլևս չի տեսագրում"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Տեսախցիկն ու խոսափողը այլևս չեն տեսաձայնագրում"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 204484c8b58a..0e056bba8df9 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ketuk lagi untuk membuka"</string> <string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tekan untuk membuka"</string> <string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string> diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml index c787ca2dd573..d58cdc89832e 100644 --- a/packages/SystemUI/res/values-in/strings_tv.xml +++ b/packages/SystemUI/res/values-in/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifikasi"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Tidak Ada Notifikasi"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon sedang merekam"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera sedang merekam"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera dan Mikrofon sedang merekam"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon berhenti merekam"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera berhenti merekam"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera dan Mikrofon berhenti merekam"</string> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 5afc8bc41f34..fa3310b228db 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ýttu aftur til að opna"</string> <string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ýttu til að opna"</string> <string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string> diff --git a/packages/SystemUI/res/values-is/strings_tv.xml b/packages/SystemUI/res/values-is/strings_tv.xml index 6d7c91c03760..eb0f45016113 100644 --- a/packages/SystemUI/res/values-is/strings_tv.xml +++ b/packages/SystemUI/res/values-is/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Tilkynningar"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Engar tilkynningar"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Hljóðnemi er að taka upp"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Myndavél er að taka upp"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Myndavél og hljóðnemi eru að taka upp"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Hljóðnemi er hættur að taka upp"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Myndavél er hætt að taka upp"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Myndavél og hljóðnemi eru hætt að taka upp"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 9c283634b81e..abf708f2da7f 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tocca ancora per aprire"</string> <string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Premi per aprire"</string> <string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string> diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml index c6760290446f..45d336923acb 100644 --- a/packages/SystemUI/res/values-it/strings_tv.xml +++ b/packages/SystemUI/res/values-it/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifiche"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nessuna notifica"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Registrazione in corso con il microfono"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Registrazione in corso con la fotocamera"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Registrazione in corso con fotocamera e microfono"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Registrazione con il microfono interrotta"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Registrazione con la fotocamera interrotta"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Registrazione con fotocamera e microfono interrotta"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index b7153b12ff3e..f03420270737 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"יש להקיש שוב כדי לפתוח את ההתראה"</string> <string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"יש להקיש כדי לפתוח"</string> <string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"יש לבטל את הנעילה כדי להשתמש ב-NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string> diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml index 46e61d0c5bb5..5c091d35bfd3 100644 --- a/packages/SystemUI/res/values-iw/strings_tv.xml +++ b/packages/SystemUI/res/values-iw/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"התראות"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"אין התראות"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"המיקרופון מקליט"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"המצלמה מקליטה"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"המצלמה והמיקרופון מקליטים"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"המיקרופון הפסיק להקליט"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"המצלמה הפסיקה להקליט"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"המצלמה והמיקרופון הפסיקו להקליט"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index a8fb87d40e1a..e17f032e961f 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"開くにはもう一度タップしてください"</string> <string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"押すと開きます"</string> <string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string> @@ -798,7 +799,7 @@ <item quantity="other">%d分</item> <item quantity="one">%d分</item> </plurals> - <string name="battery_panel_title" msgid="5931157246673665963">"電池の使用状況"</string> + <string name="battery_panel_title" msgid="5931157246673665963">"バッテリーの使用状況"</string> <string name="battery_detail_charging_summary" msgid="8821202155297559706">"充電中はバッテリー セーバーは利用できません"</string> <string name="battery_detail_switch_title" msgid="6940976502957380405">"バッテリー セーバー"</string> <string name="battery_detail_switch_summary" msgid="3668748557848025990">"パフォーマンスとバックグラウンド データを制限します"</string> diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml index 798caec1404b..c37958f2b02a 100644 --- a/packages/SystemUI/res/values-ja/strings_tv.xml +++ b/packages/SystemUI/res/values-ja/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> 経由"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"通知はありません"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"マイクで録音しています"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"カメラで録画しています"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"カメラとマイクで録画、録音しています"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"マイクが録音を停止しました"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"カメラが録画を停止しました"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"カメラとマイクが録画、録音を停止しました"</string> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index da4f5bc855f6..4363876e5e6c 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"შეეხეთ ისევ გასახსნელად"</string> <string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"დააჭირეთ გასახსნელად"</string> <string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string> diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml index b158e5cef3bf..8db4b1be7da1 100644 --- a/packages/SystemUI/res/values-ka/strings_tv.xml +++ b/packages/SystemUI/res/values-ka/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-ის მიერ"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"შეტყობინებები"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"შეტყობინებები არ არის"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"მიკროფონი იწერს"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"კამერა იწერს"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"კამერა და მიკროფონი იწერს"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"მიკროფონმა ჩაწერა შეწყვიტა"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"კამერამ ჩაწერა შეწყვიტა"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"კამერამ და მიკროფონმა ჩაწერა შეწყვიტა"</string> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index c15c6be99669..6dc3b327d0a9 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ашу үшін қайта түртіңіз"</string> <string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ашу үшін басыңыз."</string> <string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string> diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml index 36440c920793..a56b4aad9731 100644 --- a/packages/SystemUI/res/values-kk/strings_tv.xml +++ b/packages/SystemUI/res/values-kk/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> арқылы жалғанған"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Хабарландырулар"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Хабарландырулар жоқ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон жазып жатыр."</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера жазып жатыр."</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера мен микрофон жазып жатыр."</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон жазуды тоқтатты."</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера жазуды тоқтатты."</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера мен микрофон жазуды тоқтатты."</string> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 31de2be76e46..9210e624de69 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ប៉ះម្ដងទៀត ដើម្បីបើក"</string> <string name="tap_again" msgid="1315420114387908655">"ចុចម្ដងទៀត"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើដើម្បីបើក"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ចុច ដើម្បីបើក"</string> <string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បីព្យាយាមម្ដងទៀត"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ស្ថាប័នអ្នក"</string> diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml index b04cc2b7149f..c654e6d770c5 100644 --- a/packages/SystemUI/res/values-km/strings_tv.xml +++ b/packages/SystemUI/res/values-km/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"តាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ការជូនដំណឹង"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"គ្មានការជូនដំណឹងទេ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"មីក្រូហ្វូនកំពុងថត"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"កាមេរ៉ាកំពុងថត"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"កាមេរ៉ា និងមីក្រូហ្វូនកំពុងថត"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"មីក្រូហ្វូនបានឈប់ថត"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"កាមេរ៉ាបានឈប់ថត"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"កាមេរ៉ា និងមីក្រូហ្វូនបានឈប់ថត"</string> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 9b9138c44119..e32bddd6534b 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ತೆರೆಯಲು ಒತ್ತಿ"</string> <string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string> diff --git a/packages/SystemUI/res/values-kn/strings_tv.xml b/packages/SystemUI/res/values-kn/strings_tv.xml index e4b33140af11..3955a09deac3 100644 --- a/packages/SystemUI/res/values-kn/strings_tv.xml +++ b/packages/SystemUI/res/values-kn/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ಅಧಿಸೂಚನೆಗಳು"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ಕ್ಯಾಮರಾ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿವೆ"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿದೆ"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ಕ್ಯಾಮರಾ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಲಾಗಿದೆ"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿವೆ"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 044086e1114c..1dc505443b03 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -353,7 +353,7 @@ <string name="quick_settings_location_off_label" msgid="7923929131443915919">"위치 사용 중지"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"카메라 액세스"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"마이크 액세스"</string> - <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"허용됨"</string> + <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"사용 가능"</string> <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"차단됨"</string> <string name="quick_settings_media_device_label" msgid="8034019242363789941">"미디어 기기"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"다시 탭하여 열기"</string> <string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string> <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"열려면 누르세요"</string> <string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string> diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml index 8849265b3f23..b9fb537eb12c 100644 --- a/packages/SystemUI/res/values-ko/strings_tv.xml +++ b/packages/SystemUI/res/values-ko/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>에 연결됨"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"알림"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"알림 없음"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"마이크 녹음 중"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"카메라 녹화 중"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"카메라 녹화 및 마이크 녹음 중"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"마이크 녹음 중단됨"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"카메라 녹화 중단됨"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"카메라 녹화 및 마이크 녹음 중단됨"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml index 38c0185222e1..b583f242cff8 100644 --- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml @@ -48,8 +48,8 @@ </string-array> <string-array name="tile_states_battery"> <item msgid="6311253873330062961">"이용 불가"</item> - <item msgid="7838121007534579872">"꺼짐"</item> - <item msgid="1578872232501319194">"켜짐"</item> + <item msgid="7838121007534579872">"사용 안함"</item> + <item msgid="1578872232501319194">"사용"</item> </string-array> <string-array name="tile_states_dnd"> <item msgid="467587075903158357">"이용 불가"</item> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 0a0bf4c4ef96..8a26ed364e15 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ачуу үчүн кайра таптап коюңуз"</string> <string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ачуу үчүн басыңыз"</string> <string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC колдонуу үчүн түзмөктүн кулпусун ачыңыз"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string> @@ -706,11 +707,11 @@ <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Эскертмелерди башкаруу каражаттары"</string> <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"Күйүк"</string> <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"Өчүк"</string> - <string name="power_notification_controls_description" msgid="1334963837572708952">"Бул функциянын жардамы менен, ар бир колдонмо үчүн билдирменин маанилүүлүгүн 0дон 5ке чейин бааласаңыз болот. \n\n"<b>"5-деңгээл"</b>" \n- Билдирмелер тизмесинин өйдө жагында көрсөтүлөт \n- Билдирмелер толук экранда көрсөтүлөт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n"<b>"4-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n"<b>"3-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n\n"<b>"2-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n\n"<b>"1-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n- Кулпуланган экрандан жана абал тилкесинен жашырылат \n- Билдирмелер тизмесинин ылдый жагында көрсөтүлөт \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык билдирмелер бөгөттөлөт"</string> + <string name="power_notification_controls_description" msgid="1334963837572708952">"Бул функциянын жардамы менен, ар бир колдонмо үчүн билдирменин маанилүүлүгүн 0дон 5ке чейин бааласаңыз болот. \n\n"<b>"5-деңгээл"</b>" \n- Билдирмелер тизмесинин өйдө жагында көрүнөт \n- Билдирмелер толук экранда көрүнөт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n"<b>"4-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n"<b>"3-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n\n"<b>"2-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n\n"<b>"1-деңгээл"</b>" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n- Кулпуланган экрандан жана абал тилкесинен жашырылат \n- Билдирмелер тизмесинин ылдый жагында көрүнөт \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык билдирмелер бөгөттөлөт"</string> <string name="notification_header_default_channel" msgid="225454696914642444">"Билдирмелер"</string> <string name="notification_channel_disabled" msgid="928065923928416337">"Мындан ары бул билдирмелер сизге көрүнбөйт"</string> <string name="notification_channel_minimized" msgid="6892672757877552959">"Бул билдирмелер кичирейтилет"</string> - <string name="notification_channel_silenced" msgid="1995937493874511359">"Бул билдирмелер үнсүз көрсөтүлөт"</string> + <string name="notification_channel_silenced" msgid="1995937493874511359">"Бул билдирмелер үнсүз көрүнөт"</string> <string name="notification_channel_unsilenced" msgid="94878840742161152">"Бул билдирмелер тууралуу кабарлап турабыз"</string> <string name="inline_blocking_helper" msgid="2891486013649543452">"Адатта мындай билдирмелерди өткөрүп жибересиз. \nАлар көрүнө берсинби?"</string> <string name="inline_done_button" msgid="6043094985588909584">"Бүттү"</string> diff --git a/packages/SystemUI/res/values-ky/strings_tv.xml b/packages/SystemUI/res/values-ky/strings_tv.xml index 128c7e0c0a33..52b237514991 100644 --- a/packages/SystemUI/res/values-ky/strings_tv.xml +++ b/packages/SystemUI/res/values-ky/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Билдирмелер"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Билдирме жок"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон жаздырууда"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера жаздырууда"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера менен микрофон жаздырууда"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон жаздырууну токтотту"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера жаздырууну токтотту"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера менен микрофон жаздырууну токтотту"</string> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 53a0ace0ee33..bb6b235065de 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ແຕະອີກຄັ້ງເພື່ອເປີດ"</string> <string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ກົດເພື່ອເປີດ"</string> <string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string> diff --git a/packages/SystemUI/res/values-lo/strings_tv.xml b/packages/SystemUI/res/values-lo/strings_tv.xml index b8524568abb2..d2de1253f472 100644 --- a/packages/SystemUI/res/values-lo/strings_tv.xml +++ b/packages/SystemUI/res/values-lo/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ການແຈ້ງເຕືອນ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ບໍ່ມີການແຈ້ງເຕືອນ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ໄມໂຄຣໂຟນກຳລັງບັນທຶກ"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ກ້ອງຖ່າຍຮູບກຳລັງບັນທຶກ"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນກຳລັງບັນທຶກ"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ໄມໂຄຣໂຟນຢຸດການບັນທຶກແລ້ວ"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ກ້ອງຖ່າຍຮູບຢຸດການບັນທຶກແລ້ວ"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນຢຸດການບັນທຶກແລ້ວ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 56f187e2d352..3469b3e89496 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Palieskite dar kartą, kad atidarytumėte"</string> <string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Paspauskite, kad atidarytumėte"</string> <string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string> diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml index 7cd7507162c9..df23a616bae8 100644 --- a/packages/SystemUI/res/values-lt/strings_tv.xml +++ b/packages/SystemUI/res/values-lt/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Per „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Pranešimai"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nėra jokių pranešimų"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonas įrašo"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera įrašo"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ir mikrofonas įrašo"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonas nebeįrašo"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera nebeįrašo"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ir mikrofonas nebeįrašo"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 4522b98dbba3..cec582cb6a66 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Pieskarieties vēlreiz, lai atvērtu"</string> <string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Nospiediet, lai atvērtu"</string> <string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string> diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml index 4c648438ff66..e343a77a13da 100644 --- a/packages/SystemUI/res/values-lv/strings_tv.xml +++ b/packages/SystemUI/res/values-lv/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Izmantojot: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Paziņojumi"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nav paziņojumu"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Notiek ierakstīšana ar mikrofonu"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Notiek ierakstīšana ar kameru"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Notiek ierakstīšana ar kameru un mikrofonu"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Ierakstīšana ar mikrofonu apturēta"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ierakstīšana ar kameru apturēta"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ierakstīšana ar kameru un mikrofonu apturēta"</string> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 5317bca72c53..2a2e121fb134 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -243,7 +243,7 @@ <skip /> <!-- no translation found for accessibility_work_mode (1280025758672376313) --> <skip /> - <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известувањето е отфрлено."</string> + <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известувањето е отфрлено"</string> <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панел за известување"</string> <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брзи поставки."</string> <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заклучи екран."</string> @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Допрете повторно за да се отвори"</string> <string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Притиснете за да отворите"</string> <string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string> diff --git a/packages/SystemUI/res/values-mk/strings_tv.xml b/packages/SystemUI/res/values-mk/strings_tv.xml index 55d9df7b9a9c..f39f1fae81b8 100644 --- a/packages/SystemUI/res/values-mk/strings_tv.xml +++ b/packages/SystemUI/res/values-mk/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Известувања"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема известувања"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофонот снима"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камерата снима"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камерата и микрофонот снимаат"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофонот прекина со снимање"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камерата прекина со снимање"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камерата и микрофонот прекинаа со снимање"</string> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index e798c7d61dfe..95aec7d86b9d 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string> <string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"തുറക്കാൻ അമർത്തുക"</string> <string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string> diff --git a/packages/SystemUI/res/values-ml/strings_tv.xml b/packages/SystemUI/res/values-ml/strings_tv.xml index 6ae342cf9bd6..50d0280c7ff8 100644 --- a/packages/SystemUI/res/values-ml/strings_tv.xml +++ b/packages/SystemUI/res/values-ml/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> വഴി"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"അറിയിപ്പുകൾ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"മൈക്രോഫോൺ റെക്കോർഡ് ചെയ്യുകയാണ്"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ക്യാമറ റെക്കോർഡ് ചെയ്യുകയാണ്"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ക്യാമറയും മൈക്രോഫോണും റെക്കോർഡ് ചെയ്യുകയാണ്"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"മൈക്രോഫോൺ റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ക്യാമറ റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ക്യാമറയും മൈക്രോഫോണും റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 0e4cac02ea2d..1665e456ecbc 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Нээхийн тулд дахин товшино уу"</string> <string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Нээхийн тулд дарна уу"</string> <string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string> diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml index bbb302f6f07e..1b20d84a680b 100644 --- a/packages/SystemUI/res/values-mn/strings_tv.xml +++ b/packages/SystemUI/res/values-mn/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-р"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Мэдэгдэл"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Мэдэгдэл байхгүй байна"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон бичиж байна"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камер бичиж байна"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камер болон микрофон бичиж байна"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон бичихээ зогсоосон"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камер бичихээ зогсоосон"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камер болон микрофон бичихээ зогсоосон"</string> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 45a9a1bed0e5..0a79f48ffd4a 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"उघडण्यासाठी पुन्हा टॅप करा"</string> <string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"उघडण्यासाठी दाबा"</string> <string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्वाइप करा"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string> diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml index d596d95c28c9..2d79d4a77d3b 100644 --- a/packages/SystemUI/res/values-mr/strings_tv.xml +++ b/packages/SystemUI/res/values-mr/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचना"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"सूचना नाहीत"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"मायक्रोफोन रेकॉर्ड करत आहे"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"कॅमेरा रेकॉर्ड करत आहे"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"कॅमेरा आणि मायक्रोफोन रेकॉर्ड करत आहेत"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"मायक्रोफोनने रेकॉर्ड करणे थांबवले"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"कॅमेराने रेकॉर्ड करणे थांबवले"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"कॅमेरा आणि मायक्रोफोनने रेकॉर्ड करणे थांबवले"</string> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 2349e286b491..65cf32142770 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ketik lagi untuk membuka"</string> <string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tekan untuk buka"</string> <string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string> diff --git a/packages/SystemUI/res/values-ms/strings_tv.xml b/packages/SystemUI/res/values-ms/strings_tv.xml index e28d032dd9e0..9064ec4e6c2f 100644 --- a/packages/SystemUI/res/values-ms/strings_tv.xml +++ b/packages/SystemUI/res/values-ms/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Pemberitahuan"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Tiada Pemberitahuan"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon sedang merakam"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera sedang merakam"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera dan Mikrofon sedang merakam"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon berhenti merakam"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera berhenti merakam"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera dan Mikrofon berhenti merakam"</string> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 23de47fba55d..07f3a75dced5 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string> <string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ဖွင့်ရန် နှိပ်ပါ"</string> <string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string> diff --git a/packages/SystemUI/res/values-my/strings_tv.xml b/packages/SystemUI/res/values-my/strings_tv.xml index 848c403b9247..1aca9eb72364 100644 --- a/packages/SystemUI/res/values-my/strings_tv.xml +++ b/packages/SystemUI/res/values-my/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့်"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"အကြောင်းကြားချက်များ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"အကြောင်းကြားချက်များ မရှိပါ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"မိုက်ခရိုဖုန်း မှတ်တမ်းတင်နေသည်"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ကင်မရာ မှတ်တမ်းတင်နေသည်"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းက မှတ်တမ်းတင်နေသည်"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"မိုက်ခရိုဖုန်း မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ကင်မရာ မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းက မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 9c18b95f3387..6c234001ade9 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Trykk på nytt for å åpne"</string> <string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Trykk for å åpne"</string> <string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string> diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml index 11de50aff203..7eb6a29788c7 100644 --- a/packages/SystemUI/res/values-nb/strings_tv.xml +++ b/packages/SystemUI/res/values-nb/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Varsler"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ingen varsler"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen tar opp"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameraet tar opp"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameraet og mikrofonen tar opp"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen stoppet opptaket"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameraet stoppet opptaket"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameraet og mikrofonen stoppet opptaket"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 9ae2d43e26ed..40ceb59e7169 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"खोल्न पुनः ट्याप गर्नुहोस्"</string> <string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"अनलक गर्न प्रेस गर्नुहोस्"</string> <string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ"</string> diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml index 0bcc1cc74ae7..410f26f0287b 100644 --- a/packages/SystemUI/res/values-ne/strings_tv.xml +++ b/packages/SystemUI/res/values-ne/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> मार्फत"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचनाहरू"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"कुनै पनि सूचना छैन"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"माइक्रोफोनले रेकर्ड गर्दै छ"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"क्यामेराले रेकर्ड गर्दै छ"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"क्यामेरा र माइक्रोफोनले रेकर्ड गर्दै छन्"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"माइक्रोफोनले रेकर्ड गर्न छाड्यो"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"क्यामेराले रेकर्ड गर्न छाड्यो"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"क्यामेरा र माइक्रोफोनले रेकर्ड गर्न छाडे"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 155d1ad6975d..6614638253f3 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tik nog eens om te openen"</string> <string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Druk om te openen"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string> diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml index 02c00ec3b195..7aeeabfdc7e7 100644 --- a/packages/SystemUI/res/values-nl/strings_tv.xml +++ b/packages/SystemUI/res/values-nl/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Meldingen"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Geen meldingen"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Microfoon neemt op"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera neemt op"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera en microfoon nemen op"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microfoon neemt niet meer op"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera neemt niet meer op"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera en microfoon nemen niet meer op"</string> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 4d44690b5951..fab0ac601c69 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string> <string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ଖୋଲିବାକୁ ଦବାନ୍ତୁ"</string> <string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string> diff --git a/packages/SystemUI/res/values-or/strings_tv.xml b/packages/SystemUI/res/values-or/strings_tv.xml index 82890680dcbf..2669a5aaa7f5 100644 --- a/packages/SystemUI/res/values-or/strings_tv.xml +++ b/packages/SystemUI/res/values-or/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ କରୁଛି"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"କ୍ୟାମେରା ରେକର୍ଡିଂ କରୁଛି"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ କରୁଛି"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"କ୍ୟାମେରା ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 7bb60a0a80f9..7e64a2407fd4 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string> <string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ"</string> <string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string> diff --git a/packages/SystemUI/res/values-pa/strings_tv.xml b/packages/SystemUI/res/values-pa/strings_tv.xml index 22fcce8decf9..3443cfac4d70 100644 --- a/packages/SystemUI/res/values-pa/strings_tv.xml +++ b/packages/SystemUI/res/values-pa/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"ਸੂਚਨਾਵਾਂ"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਰਿਕਾਰਡ ਕਰ ਰਿਹਾ ਹੈ"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"ਕੈਮਰਾ ਰਿਕਾਰਡ ਕਰ ਰਿਹਾ ਹੈ"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹਨ"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ਕੈਮਰੇ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index ea6f2252c0cd..7c0da9d29596 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Kliknij ponownie, by otworzyć"</string> <string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Naciśnij, by otworzyć"</string> <string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string> diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml index 2371b5efe7bd..12b3777af5f8 100644 --- a/packages/SystemUI/res/values-pl/strings_tv.xml +++ b/packages/SystemUI/res/values-pl/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Przez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Powiadomienia"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Brak powiadomień"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon rejestruje"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Aparat rejestruje"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Aparat i mikrofon rejestrują"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon przestał rejestrować"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Aparat przestał rejestrować"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Aparat i mikrofon przestały rejestrować"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 2f1501b26c6c..1bfb7012aa39 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pressione para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 563e99d56547..80f4bc649ba9 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Prima para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml index 883fa3abb40b..3ae7daf30828 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Através de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificações"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Sem notificações"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"O microfone está a gravar"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"A câmara está a gravar"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A câmara e o microfone estão a gravar"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O microfone parou a gravação"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A câmara parou a gravação"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A câmara e o microfone pararam a gravação"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 2f1501b26c6c..1bfb7012aa39 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string> <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pressione para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 21026001e0fc..d82626bb44be 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Atingeți din nou pentru a deschide"</string> <string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Apăsați pentru a deschide"</string> <string name="keyguard_retry" msgid="886802522584053523">"Glisați pentru a încerca din nou"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblocați pentru a folosi NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string> diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml index 9f2869356639..54dd985cfc0f 100644 --- a/packages/SystemUI/res/values-ro/strings_tv.xml +++ b/packages/SystemUI/res/values-ro/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Prin <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificări"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nicio notificare"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Microfonul înregistrează"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera foto înregistrează"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera foto și microfonul înregistrează"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microfonul nu mai înregistrează"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera foto a oprit înregistrarea"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera foto și microfonul nu mai înregistrează"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index eeb1f3e392aa..f3768280313a 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Нажмите ещё раз, чтобы открыть"</string> <string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Нажмите, чтобы открыть."</string> <string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string> diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml index e2162eab3f29..befb5d2115d9 100644 --- a/packages/SystemUI/res/values-ru/strings_tv.xml +++ b/packages/SystemUI/res/values-ru/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Через приложение <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Уведомления"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Уведомлений нет."</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Выполняется запись с микрофона"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Выполняется запись с камеры"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Выполняется запись с камеры и микрофона"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Запись с микрофона остановлена"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Запись с камеры остановлена"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Запись с камеры и микрофона остановлена"</string> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 247b7a544cdd..1f4813ea5f38 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string> <string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"විවෘත කිරීමට ඔබන්න"</string> <string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string> diff --git a/packages/SystemUI/res/values-si/strings_tv.xml b/packages/SystemUI/res/values-si/strings_tv.xml index b7509885951c..92257c7e7c76 100644 --- a/packages/SystemUI/res/values-si/strings_tv.xml +++ b/packages/SystemUI/res/values-si/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> හරහා"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"දැනුම්දීම්"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"දැනුම්දීම් නැත"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"මයික්රෆෝනය පටිගත කරයි"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"කැමරාව පටිගත කරයි"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"කැමරාව සහ මයික්රෆෝනය පටිගත කරයි"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"මයික්රෆෝනය පටිගත කිරීම නැවැත්වීය"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"කැමරාව පටිගත කිරීම නැවැත්වීය"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"කැමරාව සහ මයික්රෆෝනය පටිගත කිරීම නැවැත්වීය"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 74b24bdd531c..966745b3789e 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Upozornenie otvoríte opätovným klepnutím"</string> <string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Stlačením otvoríte"</string> <string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string> diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml index 2b74267c5766..6910079bbadf 100644 --- a/packages/SystemUI/res/values-sk/strings_tv.xml +++ b/packages/SystemUI/res/values-sk/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Cez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Upozornenia"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Žiadne upozornenia"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofón nahráva"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nahráva"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera a mikrofón nahrávajú"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofón prestal nahrávať"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera prestala nahrávať"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera a mikrofón prestali nahrávať"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index cfb89d4c8194..7af0970e322d 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Znova se dotaknite, da odprete"</string> <string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite, če želite odpreti."</string> <string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string> diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml index 2ef97059434d..10050790fa1a 100644 --- a/packages/SystemUI/res/values-sl/strings_tv.xml +++ b/packages/SystemUI/res/values-sl/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Prek storitve <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obvestila"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ni obvestil"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Snemanje z mikrofonom"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Snemanje s fotoaparatom"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Snemanje s fotoaparatom in mikrofonom"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Ustavljeno snemanje z mikrofonom"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ustavljeno snemanje s fotoaparatom"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ustavljeno snemanje s fotoaparatom in mikrofonom"</string> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index f7753c7a5086..a948fae6de6b 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Trokit përsëri për ta hapur"</string> <string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Shtyp për të hapur"</string> <string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string> diff --git a/packages/SystemUI/res/values-sq/strings_tv.xml b/packages/SystemUI/res/values-sq/strings_tv.xml index ece59829013c..c5ce63114508 100644 --- a/packages/SystemUI/res/values-sq/strings_tv.xml +++ b/packages/SystemUI/res/values-sq/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Njoftimet"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Asnjë njoftim"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"\"Mikrofoni\" po regjistron"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"\"Kamera\" po regjistron"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"\"Kamera\" dhe \"Mikrofoni\" po regjistrojnë"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"\"Mikrofoni\" ndaloi së regjistruari"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"\"Kamera\" ndaloi së regjistruari"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"\"Kamera\" dhe \"Mikrofoni\" ndaluan së regjistruari"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 73ecc4c7b72b..499c4e1d1489 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -454,6 +454,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string> <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Притисните да бисте отворили"</string> <string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string> diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml index 38b106b30abc..d35ff3c1e746 100644 --- a/packages/SystemUI/res/values-sr/strings_tv.xml +++ b/packages/SystemUI/res/values-sr/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Обавештења"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема обавештења"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон снима"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера снима"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера и микрофон снимају"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Снимање микрофоном је заустављено"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Снимање камером је заустављено"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Снимање камером и микрофоном је заустављено"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index c27cd83f0541..86333f0e3a5c 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Tryck igen för att öppna"</string> <string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tryck för att öppna"</string> <string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string> diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml index 22f6baaa9b51..346d5d21e9b8 100644 --- a/packages/SystemUI/res/values-sv/strings_tv.xml +++ b/packages/SystemUI/res/values-sv/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Aviseringar"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Inga aviseringar"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen spelar in"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameran spelar in"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameran och mikrofonen spelar in"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen slutade spela in"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameran slutade spela in"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameran och mikrofonen slutade spelade in"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 7ac26be4c614..6b938e41d392 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Gusa tena ili ufungue"</string> <string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Bofya ili ufungue"</string> <string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string> diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml index 086a09802eed..a585e692ff34 100644 --- a/packages/SystemUI/res/values-sw/strings_tv.xml +++ b/packages/SystemUI/res/values-sw/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Arifa"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Hakuna Arifa"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Maikrofoni inarekodi"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera inarekodi"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera na Maikrofoni zinarekodi"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Maikrofoni imeacha kurekodi"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera imeacha kurekodi"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera na Maikrofoni zimeacha kurekodi"</string> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 426ddd4b3e83..b9115a74910d 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"திறக்க, மீண்டும் தட்டவும்"</string> <string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"திறப்பதற்கு அழுத்தவும்"</string> <string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string> diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml index 398ffe986d1a..1dc581d1f692 100644 --- a/packages/SystemUI/res/values-ta/strings_tv.xml +++ b/packages/SystemUI/res/values-ta/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> வழியாக"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"அறிவிப்புகள்"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"அறிவிப்புகள் எதுவுமில்லை"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"மைக்ரோஃபோன் ரெக்கார்டு செய்கிறது"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"கேமரா ரெக்கார்டு செய்கிறது"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"கேமராவும் மைக்ரோஃபோனும் ரெக்கார்டு செய்கின்றன"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"மைக்ரோஃபோன் ரெக்கார்டு செய்வதை நிறுத்திவிட்டது"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"கேமரா ரெக்கார்டு செய்வதை நிறுத்திவிட்டது"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"கேமராவும் மைக்ரோஃபோனும் ரெக்கார்டு செய்வதை நிறுத்திவிட்டன"</string> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 020d9b462c45..bcc5404af2f0 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"తెరవడానికి మళ్లీ నొక్కండి"</string> <string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"తెరవడానికి నొక్కండి"</string> <string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్లాక్ చేయండి"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string> @@ -957,7 +958,7 @@ <string name="tuner_right" msgid="8247571132790812149">"కుడి"</string> <string name="tuner_menu" msgid="363690665924769420">"మెనూ"</string> <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> అనురవర్తనం"</string> - <string name="notification_channel_alerts" msgid="3385787053375150046">"హెచ్చరికలు"</string> + <string name="notification_channel_alerts" msgid="3385787053375150046">"అలర్ట్లు"</string> <string name="notification_channel_battery" msgid="9219995638046695106">"బ్యాటరీ"</string> <string name="notification_channel_screenshot" msgid="7665814998932211997">"స్క్రీన్షాట్లు"</string> <string name="notification_channel_general" msgid="4384774889645929705">"సాధారణ సందేశాలు"</string> diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml index 33c9ec96512e..7eded1eaaa65 100644 --- a/packages/SystemUI/res/values-te/strings_tv.xml +++ b/packages/SystemUI/res/values-te/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"నోటిఫికేషన్లు"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"నోటిఫికేషన్లు లేవు"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"మైక్రోఫోన్ రికార్డింగ్ చేస్తోంది"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"కెమెరా రికార్డింగ్ చేస్తోంది"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"కెమెరా, మైక్రోఫోన్ రికార్డింగ్ చేస్తున్నాయి"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"మైక్రోఫోన్ రికార్డింగ్ చేయడం ఆపివేసింది"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"కెమెరా రికార్డింగ్ చేయడం ఆపివేసింది"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"కెమెరా, మైక్రోఫోన్ రికార్డింగ్ చేయడం ఆపివేశాయి"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index ce469f7f7178..6f7df9fdcf3f 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -353,7 +353,7 @@ <string name="quick_settings_location_off_label" msgid="7923929131443915919">"ปิดตำแหน่ง"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"สิทธิ์เข้าถึงกล้อง"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"สิทธิ์เข้าถึงไมโครโฟน"</string> - <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"มี"</string> + <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"พร้อมให้ใช้งาน"</string> <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"ถูกบล็อก"</string> <string name="quick_settings_media_device_label" msgid="8034019242363789941">"อุปกรณ์สื่อ"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"แตะอีกครั้งเพื่อเปิด"</string> <string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"กดเพื่อเปิด"</string> <string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string> diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml index 57cff1fa0720..458dc7e8425b 100644 --- a/packages/SystemUI/res/values-th/strings_tv.xml +++ b/packages/SystemUI/res/values-th/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ผ่าน <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"การแจ้งเตือน"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ไม่มีการแจ้งเตือน"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"ไมโครโฟนกำลังบันทึก"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"กล้องกำลังบันทึก"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"กล้องและไมโครโฟนกำลังบันทึก"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ไมโครโฟนหยุดบันทึกแล้ว"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"กล้องหยุดบันทึกแล้ว"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"กล้องและไมโครโฟนหยุดบันทึกแล้ว"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 8d0a8475122c..d0312b3a99f6 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"I-tap ulit upang buksan"</string> <string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pindutin para buksan"</string> <string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string> diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml index 8be6a86b389e..b45d62b96309 100644 --- a/packages/SystemUI/res/values-tl/strings_tv.xml +++ b/packages/SystemUI/res/values-tl/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Mga Notification"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Walang Notification"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Nagre-record ang Mikropono"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Nagre-record ang Camera"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Nagre-record ang Camera at Mikropono"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Huminto sa pag-record ang Mikropono"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Huminto sa pag-record ang Camera"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Huminto sa pag-record ang Camera at Mikropono"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 6b55d1c7e1d6..33eb5f3f9af2 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Açmak için tekrar dokunun"</string> <string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Açmak için basın"</string> <string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string> diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml index 28b2d77e2502..54f24c388021 100644 --- a/packages/SystemUI/res/values-tr/strings_tv.xml +++ b/packages/SystemUI/res/values-tr/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Bildirimler"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Bildirim Yok"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon kaydediyor"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera kaydediyor"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ve Mikrofon kaydediyor"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon kaydı durdu"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera kaydı durdu"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ve Mikrofon kaydı durdu"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 0a5992bf1b48..24650f751319 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -456,6 +456,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Торкніться знову, щоб відкрити"</string> <string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Натисніть, щоб відкрити"</string> <string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string> diff --git a/packages/SystemUI/res/values-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml index c86cf3190f7a..2ec6d9a59d38 100644 --- a/packages/SystemUI/res/values-uk/strings_tv.xml +++ b/packages/SystemUI/res/values-uk/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Через <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Сповіщення"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Немає сповіщень"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Мікрофон записує"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера записує"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера й мікрофон записують"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Мікрофон припинив запис"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера припинила запис"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера й мікрофон припинили запис"</string> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 5a96fa876031..5afb43d42a69 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string> <string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"کھولنے کے لیے دبائیں"</string> <string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC استعمال کرنے کیلئے غیر مقفل کریں"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string> diff --git a/packages/SystemUI/res/values-ur/strings_tv.xml b/packages/SystemUI/res/values-ur/strings_tv.xml index 5810482128b2..566b33fe633b 100644 --- a/packages/SystemUI/res/values-ur/strings_tv.xml +++ b/packages/SystemUI/res/values-ur/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"بذریعہ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"اطلاعات"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"کوئی اطلاع نہیں ہے"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"مائیکروفون ریکارڈ کر رہا ہے"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"کیمرا ریکارڈ کر رہا ہے"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"کیمرا اور مائیکروفون ریکارڈ کر رہا ہے"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"مائیکروفون نے ریکارڈ کرنا بند کر دیا"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"کیمرے نے ریکارڈ کرنا بند کر دیا"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"کیمرے اور مائیکروفون نے ریکارڈ کرنا بند کر دیا"</string> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index d96ea064aaac..7968452ec284 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Ochish uchun yana bosing"</string> <string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ochish uchun bosing"</string> <string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 54b49671be36..50e45cb9c114 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Nhấn lại để mở"</string> <string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Nhấn để mở"</string> <string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string> diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml index 21f5471045e2..014488441d73 100644 --- a/packages/SystemUI/res/values-vi/strings_tv.xml +++ b/packages/SystemUI/res/values-vi/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Thông báo"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Không có thông báo"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Micrô đang ghi"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Máy ảnh đang ghi"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Máy ảnh và micrô đang ghi"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Micrô đã dừng ghi"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Máy ảnh đã dừng ghi"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Máy ảnh và micrô đã dừng ghi"</string> </resources> diff --git a/packages/SystemUI/res/values-w390dp/config.xml b/packages/SystemUI/res/values-w390dp/config.xml new file mode 100644 index 000000000000..222d8484ce22 --- /dev/null +++ b/packages/SystemUI/res/values-w390dp/config.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright (C) 2021 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. + --> + +<resources> + <bool name="config_showBatteryEstimateQSBH">true</bool> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 3cbcf3119437..2291902333ba 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"再次点按即可打开"</string> <string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"按一下即可打开"</string> <string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml index ca814a37bda7..ed914c90e627 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"没有通知"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"麦克风正在录制"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"相机正在录制"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相机和麦克风正在录制"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麦克风已停止录制"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相机已停止录制"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相机和麦克风已停止录制"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 726947ff2e53..38228895297b 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string> <string name="tap_again" msgid="1315420114387908655">"再次輕按"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"按下即可開啟"</string> <string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml index f992b6251b46..dfc34e5f098d 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"透過 <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"沒有通知"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"麥克風正在錄音"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"相機正在錄影"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相機和麥克風正在錄影及錄音"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麥克風已停止錄音"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相機已停止錄影"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相機和麥克風已停止錄影及錄音"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 437bece4a6c3..fd6ad7ad5bd7 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"再次輕觸即可開啟"</string> <string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"按下即可開啟"</string> <string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml index 94135d255adb..869ac483d5d8 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"沒有通知"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"麥克風正在錄音"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"相機正在錄影"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相機和麥克風正在錄影及錄音"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麥克風已停止錄音"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相機已停止錄影"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相機和麥克風已停止錄影及錄音"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 6b7d577e3db9..58ecc7c3b147 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -452,6 +452,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Thepha futhi ukuze uvule"</string> <string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string> + <string name="keyguard_unlock_press" msgid="8488350566398524740">"Chofoza ukuze uvule"</string> <string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string> diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml index 79a6575d8fad..a3e525524582 100644 --- a/packages/SystemUI/res/values-zu/strings_tv.xml +++ b/packages/SystemUI/res/values-zu/strings_tv.xml @@ -26,16 +26,10 @@ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Nge-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="tv_notification_panel_title" msgid="5311050946506276154">"Izaziso"</string> <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Azikho Izaziso"</string> - <!-- no translation found for mic_recording_announcement (7587123608060316575) --> - <skip /> - <!-- no translation found for camera_recording_announcement (7240177719403759112) --> - <skip /> - <!-- no translation found for mic_and_camera_recording_announcement (8599231390508812667) --> - <skip /> - <!-- no translation found for mic_stopped_recording_announcement (7301537004900721242) --> - <skip /> - <!-- no translation found for camera_stopped_recording_announcement (8540496432367032801) --> - <skip /> - <!-- no translation found for mic_camera_stopped_recording_announcement (8708524579599977412) --> - <skip /> + <string name="mic_recording_announcement" msgid="7587123608060316575">"Imakrofoni iyarekhoda"</string> + <string name="camera_recording_announcement" msgid="7240177719403759112">"Ikhamera iyarekhoda"</string> + <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Ikhamera nemakrofoni kuyarekhoda"</string> + <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Imakrofoni iyekile ukurekhoda"</string> + <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ikhamera iyeke ukurekhoda"</string> + <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ikhemera nemakrofoni kuyekile ukurekhoda"</string> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index f5d47ce9698c..11850b4332e6 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -539,6 +539,11 @@ <item>@*android:string/status_bar_headset</item> </string-array> + + <!-- Whether to show estimate in QS header. Default to false in case there's not enough + space --> + <bool name="config_showBatteryEstimateQSBH">false</bool> + <!-- A path similar to frameworks/base/core/res/res/values/config.xml config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 90c1e402d248..3a3d30861132 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -209,6 +209,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { @Override public void onCancelled( @Nullable WindowInsetsAnimationController controller) { + // It is possible to be denied control of ime insets, which means onReady + // is never called. We still need to notify the runnables in order to + // complete the bouncer disappearing + runOnFinishImeAnimationRunnable(); + finishRunnable.run(); } }); return true; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 459f3cac89f4..23d6ebc46030 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -149,7 +149,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES; private static final boolean DEBUG_FACE = Build.IS_DEBUGGABLE; private static final boolean DEBUG_SPEW = false; - private static final int LOW_BATTERY_THRESHOLD = 20; + private static final int FINGERPRINT_LOCKOUT_RESET_DELAY_MS = 600; private static final String ACTION_FACE_UNLOCK_STARTED = "com.android.facelock.FACE_UNLOCK_STARTED"; @@ -834,7 +834,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintLockoutReset() { mFingerprintLockedOut = false; mFingerprintLockedOutPermanent = false; - updateFingerprintListeningState(); + + if (isUdfpsEnrolled()) { + // TODO(b/194825098): update the reset signal(s) + // A successful unlock will trigger a lockout reset, but there is no guarantee + // that the events will arrive in a particular order. Add a delay here in case + // an unlock is in progress. In this is a normal unlock the extra delay won't + // be noticeable. + mHandler.postDelayed(this::updateFingerprintListeningState, + FINGERPRINT_LOCKOUT_RESET_DELAY_MS); + } else { + updateFingerprintListeningState(); + } } private void setFingerprintRunningState(int fingerprintRunningState) { @@ -2407,8 +2418,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab if (isEncryptedOrLockdown(userId) && supportsFaceDetection) { mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId); } else { + final boolean isBypassEnabled = mKeyguardBypassController != null + && mKeyguardBypassController.isBypassEnabled(); mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal, - mFaceAuthenticationCallback, null /* handler */, userId); + mFaceAuthenticationCallback, null /* handler */, userId, isBypassEnabled); } setFaceRunningState(BIOMETRIC_STATE_RUNNING); } diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java index c1d448db1e63..622419a86bfc 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java @@ -17,15 +17,21 @@ package com.android.keyguard; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.PointF; import android.graphics.RectF; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import androidx.annotation.NonNull; +import com.android.settingslib.Utils; import com.android.systemui.Dumpable; +import com.android.systemui.R; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -33,16 +39,47 @@ import java.io.PrintWriter; /** * A view positioned under the notification shade. */ -public class LockIconView extends ImageView implements Dumpable { +public class LockIconView extends FrameLayout implements Dumpable { @NonNull private final RectF mSensorRect; @NonNull private PointF mLockIconCenter = new PointF(0f, 0f); private int mRadius; + private ImageView mLockIcon; + private ImageView mUnlockBgView; + + private int mLockIconColor; + public LockIconView(Context context, AttributeSet attrs) { super(context, attrs); mSensorRect = new RectF(); } + @Override + public void onFinishInflate() { + super.onFinishInflate(); + mLockIcon = findViewById(R.id.lock_icon); + mUnlockBgView = findViewById(R.id.lock_icon_bg); + } + + void updateColorAndBackgroundVisibility(boolean useBackground) { + if (useBackground) { + mLockIconColor = Utils.getColorAttrDefaultColor(getContext(), + android.R.attr.textColorPrimary); + mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg)); + mUnlockBgView.setVisibility(View.VISIBLE); + } else { + mLockIconColor = Utils.getColorAttrDefaultColor(getContext(), + R.attr.wallpaperTextColorAccent); + mUnlockBgView.setVisibility(View.GONE); + } + + mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor)); + } + + void setImageDrawable(Drawable drawable) { + mLockIcon.setImageDrawable(drawable); + } + void setCenterLocation(@NonNull PointF center, int radius) { mLockIconCenter = center; mRadius = radius; @@ -56,9 +93,12 @@ public class LockIconView extends ImageView implements Dumpable { setX(mSensorRect.left); setY(mSensorRect.top); - setLayoutParams(new FrameLayout.LayoutParams( + + final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( (int) (mSensorRect.right - mSensorRect.left), - (int) (mSensorRect.bottom - mSensorRect.top))); + (int) (mSensorRect.bottom - mSensorRect.top)); + lp.gravity = Gravity.CENTER; + setLayoutParams(lp); } @Override @@ -70,7 +110,6 @@ public class LockIconView extends ImageView implements Dumpable { return mLockIconCenter.y - mRadius; } - @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { pw.println("Center in px (x, y)= (" + mLockIconCenter.x + ", " + mLockIconCenter.y + ")"); diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 9c8582fa334d..4317e258d8f7 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -43,7 +43,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; -import com.android.settingslib.Utils; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.biometrics.AuthController; @@ -97,8 +96,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull private final AnimatedVectorDrawable mLockToUnlockIcon; @NonNull private final Drawable mLockIcon; @NonNull private final Drawable mUnlockIcon; - @NonNull private final CharSequence mUnlockedLabel; - @NonNull private final CharSequence mLockedLabel; + @NonNull private CharSequence mUnlockedLabel; + @NonNull private CharSequence mLockedLabel; @Nullable private final Vibrator mVibrator; private boolean mIsDozing; @@ -111,7 +110,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme private boolean mUserUnlockedWithBiometric; private Runnable mCancelDelayedUpdateVisibilityRunnable; - private boolean mHasUdfps; + private boolean mUdfpsSupported; private float mHeightPixels; private float mWidthPixels; private int mBottomPadding; // in pixels @@ -152,9 +151,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme final Context context = view.getContext(); mUnlockIcon = mView.getContext().getResources().getDrawable( - R.anim.lock_to_unlock, + R.drawable.ic_unlock, mView.getContext().getTheme()); - ((AnimatedVectorDrawable) mUnlockIcon).start(); mLockIcon = mView.getContext().getResources().getDrawable( R.anim.lock_to_unlock, mView.getContext().getTheme()); @@ -177,7 +175,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme protected void onViewAttached() { // we check this here instead of onInit since the FingerprintManager + FaceManager may not // have started up yet onInit - mHasUdfps = mAuthController.getUdfpsSensorLocation() != null; + mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; updateConfiguration(); updateKeyguardShowing(); @@ -307,12 +305,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } private void updateColors() { - final int color = Utils.getColorAttrDefaultColor(mView.getContext(), - R.attr.wallpaperTextColorAccent); - mFpToUnlockIcon.setTint(color); - mLockToUnlockIcon.setTint(color); - mLockIcon.setTint(color); - mUnlockIcon.setTint(color); + mView.updateColorAndBackgroundVisibility(mUdfpsSupported); } private void updateConfiguration() { @@ -321,11 +314,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mHeightPixels = metrics.heightPixels; mBottomPadding = mView.getContext().getResources().getDimensionPixelSize( R.dimen.lock_icon_margin_bottom); + + mUnlockedLabel = mView.getContext().getResources().getString( + R.string.accessibility_unlock_button); + mLockedLabel = mView.getContext() + .getResources().getString(R.string.accessibility_lock_icon); + updateLockIconLocation(); } private void updateLockIconLocation() { - if (mHasUdfps) { + if (mUdfpsSupported) { FingerprintSensorPropertiesInternal props = mAuthController.getUdfpsProps().get(0); mView.setCenterLocation(new PointF(props.sensorLocationX, props.sensorLocationY), props.sensorRadius); @@ -467,6 +466,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @Override public void onConfigChanged(Configuration newConfig) { updateConfiguration(); + updateColors(); } }; @@ -560,7 +560,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } private boolean isClickable() { - return mUdfpsEnrolled || mShowUnlockIcon; + return mUdfpsSupported || mShowUnlockIcon; } /** diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index 54e78cf0ab74..deceb951c2bb 100644 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -195,6 +195,7 @@ public class BatteryMeterView extends LinearLayout implements * @param mode desired mode (none, on, off) */ public void setPercentShowMode(@BatteryPercentMode int mode) { + if (mode == mShowPercentMode) return; mShowPercentMode = mode; updateShowPercent(); } @@ -330,7 +331,7 @@ public class BatteryMeterView extends LinearLayout implements if (mBatteryPercentView == null) { return; } - if (estimate != null) { + if (estimate != null && mShowPercentMode == MODE_ESTIMATE) { mBatteryPercentView.setText(estimate); setContentDescription(getContext().getString( R.string.accessibility_battery_level_with_estimate, @@ -485,6 +486,7 @@ public class BatteryMeterView extends LinearLayout implements pw.println(" mTextColor: #" + Integer.toHexString(mTextColor)); pw.println(" mBatteryStateUnknown: " + mBatteryStateUnknown); pw.println(" mLevel: " + mLevel); + pw.println(" mMode: " + mShowPercentMode); } private final class SettingObserver extends ContentObserver { diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java index 0ae89bc10290..b5b6b1340108 100644 --- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java @@ -16,25 +16,24 @@ package com.android.systemui; -import android.app.ActivityManager; -import android.app.Dialog; +import android.app.AlertDialog; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; -import android.os.RemoteException; import android.os.UserHandle; -import android.provider.Settings; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.qs.QSUserSwitcherEvent; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.util.settings.SecureSettings; /** * Manages notification when a guest session is resumed. @@ -43,16 +42,23 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver { private static final String TAG = "GuestResumeSessionReceiver"; - private static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in"; + @VisibleForTesting + public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in"; - private Dialog mNewSessionDialog; + @VisibleForTesting + public AlertDialog mNewSessionDialog; + private final UserTracker mUserTracker; private final UserSwitcherController mUserSwitcherController; private final UiEventLogger mUiEventLogger; + private final SecureSettings mSecureSettings; public GuestResumeSessionReceiver(UserSwitcherController userSwitcherController, - UiEventLogger uiEventLogger) { + UserTracker userTracker, UiEventLogger uiEventLogger, + SecureSettings secureSettings) { mUserSwitcherController = userSwitcherController; + mUserTracker = userTracker; mUiEventLogger = uiEventLogger; + mSecureSettings = secureSettings; } /** @@ -78,26 +84,19 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver { return; } - UserInfo currentUser; - try { - currentUser = ActivityManager.getService().getCurrentUser(); - } catch (RemoteException e) { - return; - } + UserInfo currentUser = mUserTracker.getUserInfo(); if (!currentUser.isGuest()) { return; } - ContentResolver cr = context.getContentResolver(); - int notFirstLogin = Settings.System.getIntForUser( - cr, SETTING_GUEST_HAS_LOGGED_IN, 0, userId); + int notFirstLogin = mSecureSettings.getIntForUser( + SETTING_GUEST_HAS_LOGGED_IN, 0, userId); if (notFirstLogin != 0) { mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController, mUiEventLogger, userId); mNewSessionDialog.show(); } else { - Settings.System.putIntForUser( - cr, SETTING_GUEST_HAS_LOGGED_IN, 1, userId); + mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId); } } } @@ -109,18 +108,26 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver { } } - private static class ResetSessionDialog extends SystemUIDialog implements + /** + * Dialog shown when user when asking for confirmation before deleting guest user. + */ + @VisibleForTesting + public static class ResetSessionDialog extends SystemUIDialog implements DialogInterface.OnClickListener { - private static final int BUTTON_WIPE = BUTTON_NEGATIVE; - private static final int BUTTON_DONTWIPE = BUTTON_POSITIVE; + @VisibleForTesting + public static final int BUTTON_WIPE = BUTTON_NEGATIVE; + @VisibleForTesting + public static final int BUTTON_DONTWIPE = BUTTON_POSITIVE; private final UserSwitcherController mUserSwitcherController; private final UiEventLogger mUiEventLogger; private final int mUserId; - ResetSessionDialog(Context context, UserSwitcherController userSwitcherController, - UiEventLogger uiEventLogger, int userId) { + ResetSessionDialog(Context context, + UserSwitcherController userSwitcherController, + UiEventLogger uiEventLogger, + int userId) { super(context); setTitle(context.getString(R.string.guest_wipe_session_title)); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java index 205054d68280..98ad87506819 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java @@ -93,6 +93,8 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView { @Nullable private ModalityListener mModalityListener; @Nullable private FingerprintSensorPropertiesInternal mFingerprintSensorProps; @Nullable private UdfpsDialogMeasureAdapter mUdfpsMeasureAdapter; + @Nullable @VisibleForTesting UdfpsIconController mUdfpsIconController; + public AuthBiometricFaceToFingerprintView(Context context) { super(context); @@ -107,6 +109,12 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView { super(context, attrs, injector); } + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mUdfpsIconController = new UdfpsIconController(mContext, mIconView, mIndicatorView); + } + @Modality int getActiveSensorType() { return mActiveSensorType; @@ -168,35 +176,26 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView { } @Override - @NonNull - protected IconController getIconController() { - if (mActiveSensorType == TYPE_FINGERPRINT) { - if (!(mIconController instanceof UdfpsIconController)) { - mIconController = createUdfpsIconController(); - } - return mIconController; - } - return super.getIconController(); - } - - @NonNull - protected IconController createUdfpsIconController() { - return new UdfpsIconController(getContext(), mIconView, mIndicatorView); - } - - @Override public void updateState(@BiometricState int newState) { - if (mState == STATE_HELP || mState == STATE_ERROR) { - @Modality final int currentType = mActiveSensorType; - mActiveSensorType = TYPE_FINGERPRINT; + if (mActiveSensorType == TYPE_FACE) { + if (newState == STATE_HELP || newState == STATE_ERROR) { + mActiveSensorType = TYPE_FINGERPRINT; + + setRequireConfirmation(false); + mConfirmButton.setEnabled(false); + mConfirmButton.setVisibility(View.GONE); - setRequireConfirmation(false); - mConfirmButton.setEnabled(false); - mConfirmButton.setVisibility(View.GONE); + if (mModalityListener != null) { + mModalityListener.onModalitySwitched(TYPE_FACE, mActiveSensorType); + } - if (mModalityListener != null && currentType != mActiveSensorType) { - mModalityListener.onModalitySwitched(currentType, mActiveSensorType); + // Deactivate the face icon controller so it stops drawing to the view + mFaceIconController.deactivate(); + // Then, activate this icon controller. We need to start in the "error" state + mUdfpsIconController.updateState(mState, newState); } + } else { // Fingerprint + mUdfpsIconController.updateState(mState, newState); } super.updateState(newState); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java index e8da7c51bf0d..c32c1a2f3e53 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java @@ -49,6 +49,7 @@ public class AuthBiometricFaceView extends AuthBiometricView { protected Handler mHandler; protected boolean mLastPulseLightToDark; // false = dark to light, true = light to dark protected @BiometricState int mState; + protected boolean mDeactivated; protected IconController(Context context, ImageView iconView, TextView textView) { mContext = context; @@ -67,6 +68,11 @@ public class AuthBiometricFaceView extends AuthBiometricView { } protected void animateIcon(int iconRes, boolean repeat) { + Log.d(TAG, "animateIcon, state: " + mState + ", deactivated: " + mDeactivated); + if (mDeactivated) { + return; + } + final AnimatedVectorDrawable icon = (AnimatedVectorDrawable) mContext.getDrawable(iconRes); mIconView.setImageDrawable(icon); @@ -92,12 +98,26 @@ public class AuthBiometricFaceView extends AuthBiometricView { @Override public void onAnimationEnd(Drawable drawable) { super.onAnimationEnd(drawable); + Log.d(TAG, "onAnimationEnd, mState: " + mState + ", deactivated: " + mDeactivated); + if (mDeactivated) { + return; + } + if (mState == STATE_AUTHENTICATING || mState == STATE_HELP) { pulseInNextDirection(); } } + protected void deactivate() { + mDeactivated = true; + } + protected void updateState(int lastState, int newState) { + if (mDeactivated) { + Log.w(TAG, "Ignoring updateState when deactivated: " + newState); + return; + } + final boolean lastStateIsErrorIcon = lastState == STATE_ERROR || lastState == STATE_HELP; @@ -142,7 +162,7 @@ public class AuthBiometricFaceView extends AuthBiometricView { } } - protected IconController mIconController; + @Nullable @VisibleForTesting IconController mFaceIconController; public AuthBiometricFaceView(Context context) { this(context, null); @@ -158,6 +178,12 @@ public class AuthBiometricFaceView extends AuthBiometricView { } @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mFaceIconController = new IconController(mContext, mIconView, mIndicatorView); + } + + @Override protected int getDelayAfterAuthenticatedDurationMs() { return HIDE_DELAY_MS; } @@ -187,17 +213,9 @@ public class AuthBiometricFaceView extends AuthBiometricView { return true; } - @NonNull - protected IconController getIconController() { - if (mIconController == null) { - mIconController = new IconController(mContext, mIconView, mIndicatorView); - } - return mIconController; - } - @Override public void updateState(@BiometricState int newState) { - getIconController().updateState(mState, newState); + mFaceIconController.updateState(mState, newState); if (newState == STATE_AUTHENTICATING_ANIMATING_IN || (newState == STATE_AUTHENTICATING && getSize() == AuthDialog.SIZE_MEDIUM)) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 950bd8319755..e612fb4712fc 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -72,6 +72,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; @@ -123,6 +124,7 @@ public class UdfpsController implements DozeReceiver { @NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; @Nullable private final UdfpsHbmProvider mHbmProvider; @NonNull private final KeyguardBypassController mKeyguardBypassController; + @NonNull private final ConfigurationController mConfigurationController; @VisibleForTesting @NonNull final BiometricOrientationEventListener mOrientationListener; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @@ -522,7 +524,8 @@ public class UdfpsController implements DozeReceiver { @NonNull KeyguardStateController keyguardStateController, @NonNull KeyguardBypassController keyguardBypassController, @NonNull DisplayManager displayManager, - @Main Handler mainHandler) { + @Main Handler mainHandler, + @NonNull ConfigurationController configurationController) { mContext = context; mExecution = execution; // TODO (b/185124905): inject main handler and vibrator once done prototyping @@ -557,6 +560,7 @@ public class UdfpsController implements DozeReceiver { displayManager, mainHandler); mKeyguardBypassController = keyguardBypassController; + mConfigurationController = configurationController; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists @@ -776,6 +780,7 @@ public class UdfpsController implements DozeReceiver { mDumpManager, mKeyguardViewMediator, mLockscreenShadeTransitionController, + mConfigurationController, this ); case IUdfpsOverlayController.REASON_AUTH_BP: @@ -883,11 +888,16 @@ public class UdfpsController implements DozeReceiver { private void onFingerDown(int x, int y, float minor, float major) { mExecution.assertIsMainThread(); - mKeyguardBypassController.setUserHasDeviceEntryIntent(true); if (mView == null) { Log.w(TAG, "Null view in onFingerDown"); return; } + + if (mView.getAnimationViewController() instanceof UdfpsKeyguardViewController + && !mStatusBarStateController.isDozing()) { + mKeyguardBypassController.setUserHasDeviceEntryIntent(true); + } + if (!mOnFingerDown) { playStartHaptic(); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java index eb02aa0d9cdf..d122610c395d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java @@ -22,7 +22,6 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOff import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; -import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; @@ -51,17 +50,14 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { private UdfpsDrawable mFingerprintDrawable; // placeholder private LottieAnimationView mAodFp; private LottieAnimationView mLockScreenFp; - private int mUdfpsBouncerColor; - private int mWallpaperTextColor; private int mStatusBarState; // used when highlighting fp icon: private int mTextColorPrimary; private ImageView mBgProtection; boolean mUdfpsRequested; - int mUdfpsRequestedColor; - private AnimatorSet mAnimatorSet; + private AnimatorSet mBackgroundInAnimator = new AnimatorSet(); private int mAlpha; // 0-255 // AOD anti-burn-in offsets @@ -89,20 +85,15 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { super.onFinishInflate(); mAodFp = findViewById(R.id.udfps_aod_fp); mLockScreenFp = findViewById(R.id.udfps_lockscreen_fp); - mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg); - mWallpaperTextColor = Utils.getColorAttrDefaultColor(mContext, - R.attr.wallpaperTextColorAccent); - mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext, - android.R.attr.textColorPrimary); + updateColor(); - // requires call to invalidate to update the color (see #updateColor) + // requires call to invalidate to update the color mLockScreenFp.addValueCallback( new KeyPath("**"), LottieProperty.COLOR_FILTER, - frameInfo -> new PorterDuffColorFilter(getColor(), PorterDuff.Mode.SRC_ATOP) + frameInfo -> new PorterDuffColorFilter(mTextColorPrimary, PorterDuff.Mode.SRC_ATOP) ); - mUdfpsRequested = false; mHintAnimator = ObjectAnimator.ofFloat(mLockScreenFp, "progress", 1f, 0f, 1f); mHintAnimator.setDuration(4000); @@ -148,13 +139,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { } void requestUdfps(boolean request, int color) { - if (request) { - mUdfpsRequestedColor = color; - } else { - mUdfpsRequestedColor = -1; - } mUdfpsRequested = request; - updateColor(); } void setStatusBarState(int statusBarState) { @@ -162,31 +147,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { } void updateColor() { - mWallpaperTextColor = Utils.getColorAttrDefaultColor(mContext, - R.attr.wallpaperTextColorAccent); mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary); - mLockScreenFp.invalidate(); - mBgProtection.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg)); - } - - private boolean showingUdfpsBouncer() { - return mBgProtection.getVisibility() == View.VISIBLE; - } - - - private int getColor() { - if (isUdfpsColorRequested()) { - return mUdfpsRequestedColor; - } else if (showingUdfpsBouncer()) { - return mUdfpsBouncerColor; - } else { - return mWallpaperTextColor; - } - } - - private boolean isUdfpsColorRequested() { - return mUdfpsRequested && mUdfpsRequestedColor != -1; + mBgProtection.setImageDrawable(getContext().getDrawable(R.drawable.fingerprint_bg)); + mLockScreenFp.invalidate(); // updated with a valueCallback } /** @@ -200,7 +164,13 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { @Override protected int updateAlpha() { int alpha = super.updateAlpha(); - mLockScreenFp.setImageAlpha(alpha); + mLockScreenFp.setAlpha(alpha / 255f); + if (mInterpolatedDarkAmount != 0f) { + mBgProtection.setAlpha(1f - mInterpolatedDarkAmount); + } else { + mBgProtection.setAlpha(alpha / 255f); + } + return alpha; } @@ -215,6 +185,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { void onDozeAmountChanged(float linear, float eased) { mHintAnimator.cancel(); mInterpolatedDarkAmount = eased; + updateAlpha(); updateBurnInOffsets(); } @@ -228,52 +199,21 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { /** * Animates in the bg protection circle behind the fp icon to highlight the icon. */ - void animateUdfpsBouncer(Runnable onEndAnimation) { - if (showingUdfpsBouncer() && mBgProtection.getAlpha() == 1f) { - // already fully highlighted, don't re-animate + void animateInUdfpsBouncer(Runnable onEndAnimation) { + if (mBackgroundInAnimator.isRunning()) { + // already animating in return; } - if (mAnimatorSet != null) { - mAnimatorSet.cancel(); - } - - mAnimatorSet = new AnimatorSet(); - mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mAnimatorSet.setDuration(500); - mAnimatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - mBgProtection.setVisibility(View.VISIBLE); - } - }); - - ValueAnimator fpIconColorAnim; - if (isShadeLocked()) { - // set color and fade in since we weren't showing before - mUdfpsBouncerColor = mTextColorPrimary; - fpIconColorAnim = ValueAnimator.ofInt(0, 255); - fpIconColorAnim.addUpdateListener(valueAnimator -> - mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue())); - } else { - // update icon color - fpIconColorAnim = new ValueAnimator(); - fpIconColorAnim.setIntValues( - isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor, - mTextColorPrimary); - fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance()); - fpIconColorAnim.addUpdateListener(valueAnimator -> { - mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue(); - updateColor(); - }); - } - - mAnimatorSet.playTogether( + // fade in and scale up + mBackgroundInAnimator = new AnimatorSet(); + mBackgroundInAnimator.playTogether( ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 0f, 1f), ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 0f, 1f), - ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f), - fpIconColorAnim); - mAnimatorSet.addListener(new AnimatorListenerAdapter() { + ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f)); + mBackgroundInAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mBackgroundInAnimator.setDuration(500); + mBackgroundInAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (onEndAnimation != null) { @@ -281,66 +221,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { } } }); - mAnimatorSet.start(); - } - - /** - * Animates out the bg protection circle behind the fp icon to unhighlight the icon. - */ - void animateAwayUdfpsBouncer(@Nullable Runnable onEndAnimation) { - if (!showingUdfpsBouncer()) { - // already hidden - return; - } - - if (mAnimatorSet != null) { - mAnimatorSet.cancel(); - } - - ValueAnimator fpIconColorAnim; - if (isShadeLocked()) { - // fade out - mUdfpsBouncerColor = mTextColorPrimary; - fpIconColorAnim = ValueAnimator.ofInt(255, 0); - fpIconColorAnim.addUpdateListener(valueAnimator -> - mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue())); - } else { - // update icon color - fpIconColorAnim = new ValueAnimator(); - fpIconColorAnim.setIntValues( - mTextColorPrimary, - isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor); - fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance()); - fpIconColorAnim.addUpdateListener(valueAnimator -> { - mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue(); - updateColor(); - }); - } - - mAnimatorSet = new AnimatorSet(); - mAnimatorSet.playTogether( - ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 1f, 0f), - ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 1f, 0f), - ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 1f, 0f), - fpIconColorAnim); - mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mAnimatorSet.setDuration(500); - - mAnimatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mBgProtection.setVisibility(View.GONE); - if (onEndAnimation != null) { - onEndAnimation.run(); - } - } - }); - - mAnimatorSet.start(); - } - - boolean isAnimating() { - return mAnimatorSet != null && mAnimatorSet.isRunning(); + mBackgroundInAnimator.start(); } private boolean isShadeLocked() { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 6435bdd69872..58f1254da563 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -19,6 +19,7 @@ package com.android.systemui.biometrics; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import android.annotation.NonNull; +import android.content.res.Configuration; import android.hardware.biometrics.BiometricSourceType; import android.util.MathUtils; import android.view.MotionEvent; @@ -36,6 +37,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.concurrency.DelayableExecutor; import java.io.FileDescriptor; @@ -57,6 +59,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @NonNull private final DelayableExecutor mExecutor; @NonNull private final KeyguardViewMediator mKeyguardViewMediator; @NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController; + @NonNull private final ConfigurationController mConfigurationController; @NonNull private final UdfpsController mUdfpsController; @Nullable private Runnable mCancelDelayedHintRunnable; @@ -87,6 +90,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @NonNull DumpManager dumpManager, @NonNull KeyguardViewMediator keyguardViewMediator, @NonNull LockscreenShadeTransitionController transitionController, + @NonNull ConfigurationController configurationController, @NonNull UdfpsController udfpsController) { super(view, statusBarStateController, statusBar, dumpManager); mKeyguardViewManager = statusBarKeyguardViewManager; @@ -94,6 +98,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mExecutor = mainDelayableExecutor; mKeyguardViewMediator = keyguardViewMediator; mLockScreenShadeTransitionController = transitionController; + mConfigurationController = configurationController; mUdfpsController = udfpsController; } @@ -120,6 +125,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mQsExpanded = mKeyguardViewManager.isQsExpanded(); mInputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN; mIsBouncerVisible = mKeyguardViewManager.bouncerIsOrWillBeShowing(); + mConfigurationController.addCallback(mConfigurationListener); updateAlpha(); updatePauseAuth(); @@ -136,6 +142,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mStatusBarStateController.removeCallback(mStateListener); mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor); mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false); + mConfigurationController.removeCallback(mConfigurationListener); if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) { mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null); } @@ -158,7 +165,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud pw.println("mAlpha=" + mView.getAlpha()); pw.println("mUdfpsRequested=" + mUdfpsRequested); pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested); - pw.println("mView.mUdfpsRequestedColor=" + mView.mUdfpsRequestedColor); } /** @@ -173,12 +179,17 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mShowingUdfpsBouncer = show; updatePauseAuth(); if (mShowingUdfpsBouncer) { - mView.animateUdfpsBouncer(() -> - mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(true)); + if (mStatusBarState == StatusBarState.SHADE_LOCKED) { + mView.animateInUdfpsBouncer(null); + } + + if (mKeyguardViewManager.isOccluded()) { + mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(true); + } + mView.announceForAccessibility(mView.getContext().getString( R.string.accessibility_fingerprint_bouncer)); } else { - mView.animateAwayUdfpsBouncer(null); mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false); } return true; @@ -366,7 +377,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @Override public boolean isAnimating() { - return mView.isAnimating(); + return false; } @Override @@ -407,4 +418,27 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud pw.println(getTag()); } }; + + private final ConfigurationController.ConfigurationListener mConfigurationListener = + new ConfigurationController.ConfigurationListener() { + @Override + public void onUiModeChanged() { + mView.updateColor(); + } + + @Override + public void onThemeChanged() { + mView.updateColor(); + } + + @Override + public void onOverlayChanged() { + mView.updateColor(); + } + + @Override + public void onConfigChanged(Configuration newConfig) { + mView.updateColor(); + } + }; } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java index 239a77eb2f45..9cb9a362d460 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java @@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QSFactory; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.EnhancedEstimatesImpl; +import com.android.systemui.power.dagger.PowerModule; import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; @@ -80,6 +81,7 @@ import dagger.Provides; */ @Module(includes = { MediaModule.class, + PowerModule.class, QSModule.class }) public abstract class SystemUIDefaultModule { diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 556f95642deb..46ab5f68abe9 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -41,7 +41,6 @@ import com.android.systemui.log.dagger.LogModule; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.power.dagger.PowerModule; import com.android.systemui.recents.Recents; import com.android.systemui.screenshot.dagger.ScreenshotModule; import com.android.systemui.settings.dagger.SettingsModule; @@ -102,7 +101,6 @@ import dagger.Provides; FalsingModule.class, LogModule.class, PeopleHubModule.class, - PowerModule.class, PluginModule.class, ScreenshotModule.class, SensorModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index c7c25903923a..84cb12cf5e49 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -399,6 +399,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, private boolean mPendingLock; /** + * When starting to go away, flag a need to show the PIN lock so the keyguard can be brought + * back. + */ + private boolean mPendingPinLock = false; + + /** * Whether a power button gesture (such as double tap for camera) has been detected. This is * delivered directly from {@link KeyguardService}, immediately upon the gesture being detected. * This is used in {@link #onStartedWakingUp} to decide whether to execute the pending lock, or @@ -472,6 +478,19 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { @Override + public void onKeyguardVisibilityChanged(boolean showing) { + synchronized (KeyguardViewMediator.this) { + if (!showing && mPendingPinLock) { + Log.i(TAG, "PIN lock requested, starting keyguard"); + + // Bring the keyguard back in order to show the PIN lock + mPendingPinLock = false; + doKeyguardLocked(null); + } + } + } + + @Override public void onUserSwitching(int userId) { if (DEBUG) Log.d(TAG, String.format("onUserSwitching %d", userId)); // Note that the mLockPatternUtils user has already been updated from setCurrentUser. @@ -591,6 +610,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, + "showing; need to show keyguard so user can enter sim pin"); doKeyguardLocked(null); } else { + mPendingPinLock = true; resetStateLocked(); } } @@ -739,6 +759,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, @Override public void onBouncerVisiblityChanged(boolean shown) { synchronized (KeyguardViewMediator.this) { + if (shown) { + mPendingPinLock = false; + } adjustStatusBarLocked(shown, false); } } @@ -2783,7 +2806,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } - private void setShowingLocked(boolean showing) { + void setShowingLocked(boolean showing) { setShowingLocked(showing, false /* forceCallbacks */); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index e9b19e5cfa6f..59e5eb8d6ac8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -28,13 +28,17 @@ import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; +import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.qs.customize.QSCustomizer; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * Wrapper view with background which contains {@link QSPanel} and {@link QuickStatusBarHeader} */ -public class QSContainerImpl extends FrameLayout { +public class QSContainerImpl extends FrameLayout implements Dumpable { private final Point mSizePoint = new Point(); private int mFancyClippingTop; @@ -296,4 +300,11 @@ public class QSContainerImpl extends FrameLayout { mFancyClippingBottom, mFancyClippingRadii, Path.Direction.CW); invalidate(); } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println(getClass().getSimpleName() + " updateClippingPath: top(" + + mFancyClippingTop + ") bottom(" + mFancyClippingBottom + ") mClippingEnabled(" + + mClippingEnabled + ")"); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 04f692dcc1e6..c9230d684b1b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -36,8 +36,10 @@ import android.widget.FrameLayout.LayoutParams; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; +import com.android.systemui.dump.DumpManager; import com.android.systemui.media.MediaHost; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; @@ -131,6 +133,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca */ private boolean mAnimateNextQsUpdate; + private DumpManager mDumpManager; + @Inject public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler, InjectionInflationController injectionInflater, QSTileHost qsTileHost, @@ -139,7 +143,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca @Named(QUICK_QS_PANEL) MediaHost qqsMediaHost, KeyguardBypassController keyguardBypassController, QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags, - FalsingManager falsingManager) { + FalsingManager falsingManager, DumpManager dumpManager) { mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler; mInjectionInflater = injectionInflater; mCommandQueue = commandQueue; @@ -153,6 +157,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mFalsingManager = falsingManager; mBypassController = keyguardBypassController; mStatusBarStateController = statusBarStateController; + mDumpManager = dumpManager; } @Override @@ -197,6 +202,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSContainerImplController = qsFragmentComponent.getQSContainerImplController(); mQSContainerImplController.init(); mContainer = mQSContainerImplController.getView(); + mDumpManager.registerDumpable(mContainer.getClass().getName(), mContainer); mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter, mFalsingManager); mQSAnimator = qsFragmentComponent.getQSAnimator(); @@ -248,6 +254,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSCustomizerController.setQs(null); mQsDetailDisplayer.setQsPanelController(null); mScrollListener = null; + mDumpManager.unregisterDumpable(mContainer.getClass().getName()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 425bdc24fe1b..1b4ee734a491 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -27,12 +27,15 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import androidx.annotation.VisibleForTesting; + import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.RemeasuringLinearLayout; import com.android.systemui.R; @@ -386,19 +389,18 @@ public class QSPanel extends LinearLayout implements Tunable { if (mediaView != null) { index = indexOfChild(mediaView); } + if (mSecurityFooter.getParent() == this && indexOfChild(mSecurityFooter) < index) { + // When we remove the securityFooter to rearrange, the index of media will go + // down by one, so we correct it + index--; + } switchToParent(mSecurityFooter, this, index); } } } private void switchToParent(View child, ViewGroup parent, int index) { - ViewGroup currentParent = (ViewGroup) child.getParent(); - if (currentParent != parent || currentParent.indexOfChild(child) != index) { - if (currentParent != null) { - currentParent.removeView(child); - } - parent.addView(child, index); - } + switchToParent(child, parent, index, getDumpableTag()); } /** Call when orientation has changed and MediaHost needs to be adjusted. */ @@ -767,4 +769,29 @@ public class QSPanel extends LinearLayout implements Tunable { interface OnConfigurationChangedListener { void onConfigurationChange(Configuration newConfig); } + + @VisibleForTesting + static void switchToParent(View child, ViewGroup parent, int index, String tag) { + if (parent == null) { + Log.w(tag, "Trying to move view to null parent", + new IllegalStateException()); + return; + } + ViewGroup currentParent = (ViewGroup) child.getParent(); + if (currentParent != parent) { + if (currentParent != null) { + currentParent.removeView(child); + } + parent.addView(child, index); + return; + } + // Same parent, we are just changing indices + int currentIndex = parent.indexOfChild(child); + if (currentIndex == index) { + // We want to be in the same place. Nothing to do here + return; + } + parent.removeView(child); + parent.addView(child, index); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index cd9db614e477..77906abce625 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -95,6 +95,9 @@ public class QuickStatusBarHeader extends FrameLayout { private List<String> mRssiIgnoredSlots; private boolean mIsSingleCarrier; + private boolean mHasCenterCutout; + private boolean mConfigShowBatteryEstimate; + public QuickStatusBarHeader(Context context, AttributeSet attrs) { super(context, attrs); } @@ -203,9 +206,19 @@ public class QuickStatusBarHeader extends FrameLayout { mPrivacyContainer.setLayoutParams(lp); } + private void updateBatteryMode() { + if (mConfigShowBatteryEstimate && !mHasCenterCutout) { + mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); + } else { + mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON); + } + } + void updateResources() { Resources resources = mContext.getResources(); + mConfigShowBatteryEstimate = resources.getBoolean(R.bool.config_showBatteryEstimateQSBH); + mRoundedCornerPadding = resources.getDimensionPixelSize( R.dimen.rounded_corner_content_padding); @@ -246,6 +259,7 @@ public class QuickStatusBarHeader extends FrameLayout { .getDimensionPixelSize(R.dimen.qqs_layout_margin_top); mHeaderQsPanel.setLayoutParams(qqsLP); + updateBatteryMode(); updateHeadersPadding(); updateAnimators(); } @@ -384,14 +398,14 @@ public class QuickStatusBarHeader extends FrameLayout { mClockIconsSeparatorLayoutParams.width = 0; setSeparatorVisibility(false); mShowClockIconsSeparator = false; - mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); + mHasCenterCutout = false; } else { datePrivacySeparatorLayoutParams.width = topCutout.width(); mDatePrivacySeparator.setVisibility(View.VISIBLE); mClockIconsSeparatorLayoutParams.width = topCutout.width(); mShowClockIconsSeparator = true; setSeparatorVisibility(mKeyguardExpansionFraction == 0f); - mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON); + mHasCenterCutout = true; } } mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams); @@ -399,6 +413,8 @@ public class QuickStatusBarHeader extends FrameLayout { mCutOutPaddingLeft = padding.first; mCutOutPaddingRight = padding.second; mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top; + + updateBatteryMode(); updateHeadersPadding(); return super.onApplyWindowInsets(insets); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java index ce6e46937c25..93e5021fd6e0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java @@ -45,9 +45,12 @@ import androidx.concurrent.futures.CallbackToFutureAdapter; import androidx.concurrent.futures.CallbackToFutureAdapter.Completer; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.dagger.qualifiers.Background; import com.google.common.util.concurrent.ListenableFuture; +import java.util.concurrent.Executor; + import javax.inject.Inject; /** @@ -63,6 +66,8 @@ public class ScrollCaptureClient { private static final String TAG = LogConfig.logTag(ScrollCaptureClient.class); + private final Executor mBgExecutor; + /** * Represents the connection to a target window and provides a mechanism for requesting tiles. */ @@ -155,8 +160,10 @@ public class ScrollCaptureClient { private IBinder mHostWindowToken; @Inject - public ScrollCaptureClient(@UiContext Context context, IWindowManager windowManagerService) { + public ScrollCaptureClient(IWindowManager windowManagerService, + @Background Executor bgExecutor, @UiContext Context context) { requireNonNull(context.getDisplay(), "context must be associated with a Display!"); + mBgExecutor = bgExecutor; mWindowManagerService = windowManagerService; } @@ -220,21 +227,25 @@ public class ScrollCaptureClient { return ""; } SessionWrapper session = new SessionWrapper(connection, response.getWindowBounds(), - response.getBoundsInWindow(), maxPages); + response.getBoundsInWindow(), maxPages, mBgExecutor); session.start(completer); return "IScrollCaptureCallbacks#onCaptureStarted"; }); } private static class SessionWrapper extends IScrollCaptureCallbacks.Stub implements Session, - IBinder.DeathRecipient { + IBinder.DeathRecipient, ImageReader.OnImageAvailableListener { private IScrollCaptureConnection mConnection; + private final Executor mBgExecutor; + private final Object mLock = new Object(); private ImageReader mReader; private final int mTileHeight; private final int mTileWidth; private Rect mRequestRect; + private Rect mCapturedArea; + private Image mCapturedImage; private boolean mStarted; private final int mTargetHeight; @@ -247,7 +258,8 @@ public class ScrollCaptureClient { private Completer<Void> mEndCompleter; private SessionWrapper(IScrollCaptureConnection connection, Rect windowBounds, - Rect boundsInWindow, float maxPages) throws RemoteException { + Rect boundsInWindow, float maxPages, Executor bgExecutor) + throws RemoteException { mConnection = requireNonNull(connection); mConnection.asBinder().linkToDeath(SessionWrapper.this, 0); mWindowBounds = requireNonNull(windowBounds); @@ -259,7 +271,7 @@ public class ScrollCaptureClient { mTileWidth = mBoundsInWindow.width(); mTileHeight = pxPerTile / mBoundsInWindow.width(); mTargetHeight = (int) (mBoundsInWindow.height() * maxPages); - + mBgExecutor = bgExecutor; if (DEBUG_SCROLL) { Log.d(TAG, "boundsInWindow: " + mBoundsInWindow); Log.d(TAG, "tile size: " + mTileWidth + "x" + mTileHeight); @@ -289,6 +301,7 @@ public class ScrollCaptureClient { mReader = ImageReader.newInstance(mTileWidth, mTileHeight, PixelFormat.RGBA_8888, MAX_TILES, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); mStartCompleter = completer; + mReader.setOnImageAvailableListenerWithExecutor(this, mBgExecutor); try { mCancellationSignal = mConnection.startCapture(mReader.getSurface(), this); completer.addCancellationListener(() -> { @@ -339,9 +352,34 @@ public class ScrollCaptureClient { @BinderThread @Override - public void onImageRequestCompleted(int flags, Rect contentArea) { - Image image = mReader.acquireLatestImage(); - mTileRequestCompleter.set(new CaptureResult(image, mRequestRect, contentArea)); + public void onImageRequestCompleted(int flagsUnused, Rect contentArea) { + synchronized (mLock) { + mCapturedArea = contentArea; + if (mCapturedImage != null || (mCapturedArea == null || mCapturedArea.isEmpty())) { + completeCaptureRequest(); + } + } + } + + /** @see ImageReader.OnImageAvailableListener */ + @Override + public void onImageAvailable(ImageReader reader) { + synchronized (mLock) { + mCapturedImage = mReader.acquireLatestImage(); + if (mCapturedArea != null) { + completeCaptureRequest(); + } + } + } + + /** Produces a result for the caller as soon as both asynchronous results are received. */ + private void completeCaptureRequest() { + CaptureResult result = + new CaptureResult(mCapturedImage, mRequestRect, mCapturedArea); + mCapturedImage = null; + mRequestRect = null; + mCapturedArea = null; + mTileRequestCompleter.set(result); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java index 39d6c4f03585..1ad253e7f867 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java @@ -354,10 +354,9 @@ public class BrightnessController implements ToggleSlider.Listener { convertGammaToLinearFloat(value, minBacklight, maxBacklight), maxBacklight); if (stopTracking) { - // Log brightness as a value between 0-1000 directly correlated to brightnesses 0-1.0 + // TODO(brightnessfloat): change to use float value instead. MetricsLogger.action(mContext, metric, - Math.round(MathUtils.constrainedMap(0, 1000, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, valFloat))); + BrightnessSynchronizer.brightnessFloatToInt(valFloat)); } setBrightness(valFloat); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 92922b634d64..3890c1aa4e4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -821,6 +821,16 @@ public class KeyguardIndicationController { } } + private void showTryFingerprintMsg() { + if (mKeyguardUpdateMonitor.isUdfpsAvailable()) { + // if udfps available, there will always be a tappable affordance to unlock + // For example, the lock icon + showTransientIndication(R.string.keyguard_unlock_press); + } else { + showTransientIndication(R.string.keyguard_try_fingerprint); + } + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("KeyguardIndicationController:"); pw.println(" mInitialTextColorState: " + mInitialTextColorState); @@ -891,7 +901,7 @@ public class KeyguardIndicationController { return; } - boolean showSwipeToUnlock = + boolean showActionToUnlock = msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; if (mStatusBarKeyguardViewManager.isBouncerShowing()) { mStatusBarKeyguardViewManager.showBouncerMessage(helpString, @@ -899,13 +909,11 @@ public class KeyguardIndicationController { } else if (mKeyguardUpdateMonitor.isScreenOn()) { if (biometricSourceType == BiometricSourceType.FACE && shouldSuppressFaceMsgAndShowTryFingerprintMsg()) { - // suggest trying fingerprint - showTransientIndication(R.string.keyguard_try_fingerprint); + showTryFingerprintMsg(); return; } - showTransientIndication(helpString, false /* isError */, showSwipeToUnlock); - } - if (showSwipeToUnlock) { + showTransientIndication(helpString, false /* isError */, showActionToUnlock); + } else if (showActionToUnlock) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK), TRANSIENT_BIOMETRIC_ERROR_TIMEOUT); } @@ -921,8 +929,7 @@ public class KeyguardIndicationController { && shouldSuppressFaceMsgAndShowTryFingerprintMsg() && !mStatusBarKeyguardViewManager.isBouncerShowing() && mKeyguardUpdateMonitor.isScreenOn()) { - // suggest trying fingerprint - showTransientIndication(R.string.keyguard_try_fingerprint); + showTryFingerprintMsg(); return; } if (msgId == FaceManager.FACE_ERROR_TIMEOUT) { @@ -931,11 +938,10 @@ public class KeyguardIndicationController { if (!mStatusBarKeyguardViewManager.isBouncerShowing() && mKeyguardUpdateMonitor.isUdfpsEnrolled() && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) { - // suggest trying fingerprint - showTransientIndication(R.string.keyguard_try_fingerprint); + showTryFingerprintMsg(); } else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) { mStatusBarKeyguardViewManager.showBouncerMessage( - mContext.getResources().getString(R.string.keyguard_try_fingerprint), + mContext.getResources().getString(R.string.keyguard_unlock_press), mInitialTextColorState ); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 9846b28ba5f9..41c88cc0a74a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -154,15 +154,6 @@ public class AmbientState { return mStackHeight; } - /** - * @return Height of notifications panel, with the animation from pulseHeight accounted for. - */ - // TODO(b/192348384): move this logic to getStackHeight, and remove this and getInnerHeight - public float getPulseStackHeight() { - float pulseHeight = Math.min(mPulseHeight, mStackHeight); - return MathUtils.lerp(mStackHeight, pulseHeight, mDozeAmount); - } - /** Tracks the state from AlertingNotificationManager#hasNotifications() */ private boolean mHasAlertEntries; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index b36dc56ffdf9..2c810c93b2ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -157,15 +157,13 @@ public class StackScrollAlgorithm { // After the shelf has updated its yTranslation, explicitly set alpha=0 for view below shelf // to skip rendering them in the hardware layer. We do not set them invisible because that // runs invalidate & onDraw when these views return onscreen, which is more expensive. + if (shelf.getViewState().hidden) { + // When the shelf is hidden, it won't clip views, so we don't hide rows + return; + } final float shelfTop = shelf.getViewState().yTranslation; for (ExpandableView view : algorithmState.visibleChildren) { - if (view instanceof ExpandableNotificationRow) { - ExpandableNotificationRow row = (ExpandableNotificationRow) view; - if (row.isHeadsUp() || row.isHeadsUpAnimatingAway()) { - continue; - } - } final float viewTop = view.getViewState().yTranslation; if (viewTop >= shelfTop) { view.getViewState().alpha = 0; @@ -447,19 +445,16 @@ public class StackScrollAlgorithm { // to shelf start, thereby hiding all notifications (except the first one, which // we later unhide in updatePulsingState) // TODO(b/192348384): merge InnerHeight with StackHeight - final int stackBottom; - if (ambientState.isBypassEnabled()) { - // We want to use the stackHeight when pulse expanding, since the animation - // isn't currently optimized if the pulseHeight is continuously changing - // Let's improve this when we're merging the heights above - stackBottom = ambientState.isPulseExpanding() - ? (int) ambientState.getStackHeight() - : ambientState.getInnerHeight(); - } else { - stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing() - ? ambientState.getInnerHeight() - : (int) ambientState.getPulseStackHeight(); - } + // Note: Bypass pulse looks different, but when it is not expanding, we need + // to use the innerHeight which doesn't update continuously, otherwise we show + // more notifications than we should during this special transitional states. + boolean bypassPulseNotExpanding = ambientState.isBypassEnabled() + && ambientState.isOnKeyguard() && !ambientState.isPulseExpanding(); + final int stackBottom = + !ambientState.isShadeExpanded() || ambientState.isDozing() + || bypassPulseNotExpanding + ? ambientState.getInnerHeight() + : (int) ambientState.getStackHeight(); final int shelfStart = stackBottom - ambientState.getShelf().getIntrinsicHeight(); viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt index ec669711e2db..3a4a819bc623 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt @@ -222,6 +222,7 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr pw.println(" launchingAffordance: $launchingAffordance") pw.println(" qSExpanded: $qSExpanded") pw.println(" hasFaceFeature: $hasFaceFeature") + pw.println(" userHasDeviceEntryIntent: $userHasDeviceEntryIntent") } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 12e85beba0c6..15e0716f8c49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -631,6 +631,9 @@ public class NotificationPanelViewController extends PanelViewController { private int mScreenCornerRadius; private boolean mQSAnimatingHiddenFromCollapsed; + private int mQsClipTop; + private int mQsClipBottom; + private boolean mQsVisible; private final ContentResolver mContentResolver; private final Executor mUiExecutor; @@ -2336,6 +2339,9 @@ public class NotificationPanelViewController extends PanelViewController { final int startTop = mKeyguardStatusAreaClipBounds.top; final int startRight = mKeyguardStatusAreaClipBounds.right; final int startBottom = mKeyguardStatusAreaClipBounds.bottom; + if (mQsClippingAnimation != null) { + mQsClippingAnimation.cancel(); + } mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration); @@ -2399,9 +2405,12 @@ public class NotificationPanelViewController extends PanelViewController { mQsTranslationForFullShadeTransition = qsTranslation; updateQsFrameTranslation(); float currentTranslation = mQsFrame.getTranslationY(); - mQs.setFancyClipping(( - int) (top - currentTranslation), - (int) (bottom - currentTranslation), + mQsClipTop = (int) (top - currentTranslation); + mQsClipBottom = (int) (bottom - currentTranslation); + mQsVisible = qsVisible; + mQs.setFancyClipping( + mQsClipTop, + mQsClipBottom, radius, qsVisible && !mShouldUseSplitNotificationShade); } @@ -3239,7 +3248,10 @@ public class NotificationPanelViewController extends PanelViewController { switch (mBarState) { case KEYGUARD: if (!mDozingOnDown) { - if (mKeyguardBypassController.getBypassEnabled()) { + if (mUpdateMonitor.isFaceEnrolled() + && !mUpdateMonitor.isFaceDetectionRunning() + && !mUpdateMonitor.getUserCanSkipBouncer( + KeyguardUpdateMonitor.getCurrentUser())) { mUpdateMonitor.requestFaceAuth(true); } else { mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT, @@ -3730,7 +3742,10 @@ public class NotificationPanelViewController extends PanelViewController { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { super.dump(fd, pw, args); - pw.println(" gestureExclusionRect: " + calculateGestureExclusionRect()); + pw.println(" gestureExclusionRect: " + calculateGestureExclusionRect() + + " applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom + + ") qsVisible(" + mQsVisible + ); if (mKeyguardStatusBar != null) { mKeyguardStatusBar.dump(fd, pw, args); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java index 5e105bb64350..246810a2d70b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -296,8 +296,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW if (mKeyguardPreferredRefreshRate > 0) { boolean onKeyguard = state.mStatusBarState == StatusBarState.KEYGUARD - && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway - && !state.mDozing; + && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway; if (onKeyguard && mAuthController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())) { mLpChanged.preferredMaxDisplayRefreshRate = mKeyguardPreferredRefreshRate; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index f10f4fef5292..8f1a5782e779 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -23,6 +23,7 @@ import static com.android.systemui.DejankUtils.whitelistIpcs; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.AlertDialog; import android.app.Dialog; import android.app.IActivityTaskManager; import android.content.BroadcastReceiver; @@ -64,16 +65,18 @@ import com.android.systemui.R; import com.android.systemui.SystemUISecondaryUserService; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.qs.QSUserSwitcherEvent; import com.android.systemui.qs.tiles.UserDetailView; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.telephony.TelephonyListenerManager; import com.android.systemui.user.CreateUserActivity; +import com.android.systemui.util.settings.SecureSettings; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -104,9 +107,12 @@ public class UserSwitcherController implements Dumpable { private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; protected final Context mContext; + protected final UserTracker mUserTracker; protected final UserManager mUserManager; + private final ContentObserver mSettingsObserver; private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); - private final GuestResumeSessionReceiver mGuestResumeSessionReceiver; + @VisibleForTesting + final GuestResumeSessionReceiver mGuestResumeSessionReceiver; private final KeyguardStateController mKeyguardStateController; protected final Handler mHandler; private final ActivityStarter mActivityStarter; @@ -115,21 +121,24 @@ public class UserSwitcherController implements Dumpable { private final IActivityTaskManager mActivityTaskManager; private ArrayList<UserRecord> mUsers = new ArrayList<>(); - private Dialog mExitGuestDialog; - private Dialog mAddUserDialog; + @VisibleForTesting + AlertDialog mExitGuestDialog; + @VisibleForTesting + Dialog mAddUserDialog; private int mLastNonGuestUser = UserHandle.USER_SYSTEM; private boolean mResumeUserOnGuestLogout = true; private boolean mSimpleUserSwitcher; // When false, there won't be any visual affordance to add a new user from the keyguard even if // the user is unlocked private boolean mAddUsersFromLockScreen; - private boolean mPauseRefreshUsers; + @VisibleForTesting + boolean mPauseRefreshUsers; private int mSecondaryUser = UserHandle.USER_NULL; private Intent mSecondaryUserServiceIntent; private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); private final UiEventLogger mUiEventLogger; public final DetailAdapter mUserDetailAdapter; - private final Executor mUiBgExecutor; + private final Executor mBgExecutor; private final boolean mGuestUserAutoCreated; private final AtomicBoolean mGuestIsResetting; private final AtomicBoolean mGuestCreationScheduled; @@ -137,6 +146,8 @@ public class UserSwitcherController implements Dumpable { @Inject public UserSwitcherController(Context context, + UserManager userManager, + UserTracker userTracker, KeyguardStateController keyguardStateController, @Main Handler handler, ActivityStarter activityStarter, @@ -146,16 +157,19 @@ public class UserSwitcherController implements Dumpable { TelephonyListenerManager telephonyListenerManager, IActivityTaskManager activityTaskManager, UserDetailAdapter userDetailAdapter, - @UiBackground Executor uiBgExecutor) { + SecureSettings secureSettings, + @Background Executor bgExecutor) { mContext = context; + mUserTracker = userTracker; mBroadcastDispatcher = broadcastDispatcher; mTelephonyListenerManager = telephonyListenerManager; mActivityTaskManager = activityTaskManager; mUiEventLogger = uiEventLogger; mFalsingManager = falsingManager; - mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(this, mUiEventLogger); + mGuestResumeSessionReceiver = new GuestResumeSessionReceiver( + this, mUserTracker, mUiEventLogger, secureSettings); mUserDetailAdapter = userDetailAdapter; - mUiBgExecutor = uiBgExecutor; + mBgExecutor = bgExecutor; if (!UserManager.isGuestUserEphemeral()) { mGuestResumeSessionReceiver.register(mBroadcastDispatcher); } @@ -166,7 +180,7 @@ public class UserSwitcherController implements Dumpable { mKeyguardStateController = keyguardStateController; mHandler = handler; mActivityStarter = activityStarter; - mUserManager = UserManager.get(context); + mUserManager = userManager; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_ADDED); filter.addAction(Intent.ACTION_USER_REMOVED); @@ -185,6 +199,15 @@ public class UserSwitcherController implements Dumpable { mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, PERMISSION_SELF, null /* scheduler */); + mSettingsObserver = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + mSimpleUserSwitcher = shouldUseSimpleUserSwitcher(); + mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; + refreshUsers(UserHandle.USER_NULL); + }; + }; mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, mSettingsObserver); @@ -246,11 +269,11 @@ public class UserSwitcherController implements Dumpable { return null; } ArrayList<UserRecord> records = new ArrayList<>(infos.size()); - int currentId = ActivityManager.getCurrentUser(); + int currentId = mUserTracker.getUserId(); // Check user switchability of the foreground user since SystemUI is running in // User 0 boolean canSwitchUsers = mUserManager.getUserSwitchability( - UserHandle.of(ActivityManager.getCurrentUser())) == SWITCHABILITY_STATUS_OK; + UserHandle.of(mUserTracker.getUserId())) == SWITCHABILITY_STATUS_OK; UserInfo currentUserInfo = null; UserRecord guestRecord = null; @@ -391,7 +414,7 @@ public class UserSwitcherController implements Dumpable { } public void logoutCurrentUser() { - int currentUser = ActivityManager.getCurrentUser(); + int currentUser = mUserTracker.getUserId(); if (currentUser != UserHandle.USER_SYSTEM) { pauseRefreshUsers(); ActivityManager.logoutCurrentUser(); @@ -403,7 +426,7 @@ public class UserSwitcherController implements Dumpable { Log.w(TAG, "User " + userId + " could not removed."); return; } - if (ActivityManager.getCurrentUser() == userId) { + if (mUserTracker.getUserId() == userId) { switchToUserId(UserHandle.USER_SYSTEM); } if (mUserManager.removeUser(userId)) { @@ -411,7 +434,8 @@ public class UserSwitcherController implements Dumpable { } } - private void onUserListItemClicked(UserRecord record) { + @VisibleForTesting + void onUserListItemClicked(UserRecord record) { int id; if (record.isGuest && record.info == null) { // No guest user. Create one. @@ -429,7 +453,7 @@ public class UserSwitcherController implements Dumpable { id = record.info.id; } - int currUserId = ActivityManager.getCurrentUser(); + int currUserId = mUserTracker.getUserId(); if (currUserId == id) { if (record.isGuest) { showExitGuestDialog(id); @@ -587,15 +611,6 @@ public class UserSwitcherController implements Dumpable { } }; - private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { - public void onChange(boolean selfChange) { - mSimpleUserSwitcher = shouldUseSimpleUserSwitcher(); - mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; - refreshUsers(UserHandle.USER_NULL); - }; - }; - @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("UserSwitcherController state:"); @@ -654,13 +669,7 @@ public class UserSwitcherController implements Dumpable { * UserHandle.USER_NULL}, then switch immediately to the newly created guest user. */ public void removeGuestUser(@UserIdInt int guestUserId, @UserIdInt int targetUserId) { - UserInfo currentUser; - try { - currentUser = ActivityManager.getService().getCurrentUser(); - } catch (RemoteException e) { - Log.e(TAG, "Couldn't remove guest because ActivityManager is dead"); - return; - } + UserInfo currentUser = mUserTracker.getUserInfo(); if (currentUser.id != guestUserId) { Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")" + " is not current user (" + currentUser.id + ")"); @@ -709,7 +718,7 @@ public class UserSwitcherController implements Dumpable { return; } - mUiBgExecutor.execute(() -> { + mBgExecutor.execute(() -> { int newGuestId = createGuest(); mGuestCreationScheduled.set(false); mGuestIsResetting.set(false); @@ -874,9 +883,9 @@ public class UserSwitcherController implements Dumpable { private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) { EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(mContext, - UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser()); + UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId()); if (admin != null && !RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext, - UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) { + UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId())) { record.isDisabledByAdmin = true; record.enforcedAdmin = admin; } else { @@ -1088,7 +1097,8 @@ public class UserSwitcherController implements Dumpable { } } - private final class AddUserDialog extends SystemUIDialog implements + @VisibleForTesting + final class AddUserDialog extends SystemUIDialog implements DialogInterface.OnClickListener { public AddUserDialog(Context context) { diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java index df889f2c2ca6..35251002fb7b 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java @@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QSFactory; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.EnhancedEstimatesImpl; +import com.android.systemui.power.dagger.PowerModule; import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; @@ -81,6 +82,7 @@ import dagger.Provides; * overridden by the System UI implementation. */ @Module(includes = { + PowerModule.class, QSModule.class }, subcomponents = { diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java index 19ed2848ca6f..b38fc77fd131 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java @@ -281,18 +281,24 @@ public class ProximitySensor implements ThresholdSensor { mLastPrimaryEvent = event; - if (event.getBelow() && mSecondaryThresholdSensor.isLoaded()) { - logDebug("Primary sensor is near. Checking secondary."); + if (mSecondarySafe && mSecondaryThresholdSensor.isLoaded()) { + logDebug("Primary sensor reported " + (event.getBelow() ? "near" : "far") + + ". Checking secondary."); if (mCancelSecondaryRunnable == null) { mSecondaryThresholdSensor.resume(); } - } else { - if (!mSecondaryThresholdSensor.isLoaded()) { - logDebug("Primary sensor event: " + event.getBelow() + ". No secondary."); - } else { - logDebug("Primary sensor event: " + event.getBelow() + "."); - } + return; + } + + if (!mSecondaryThresholdSensor.isLoaded()) { + logDebug("Primary sensor event: " + event.getBelow() + ". No secondary."); onSensorEvent(event); + } else if (event.getBelow()) { + logDebug("Primary sensor event: " + event.getBelow() + ". Checking secondary."); + if (mCancelSecondaryRunnable != null) { + mCancelSecondaryRunnable.run(); + } + mSecondaryThresholdSensor.resume(); } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index e9061afb647d..ec4dfba87af0 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -513,7 +513,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { public void testTriesToAuthenticate_whenBouncer() { setKeyguardBouncerVisibility(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); verify(mFaceManager).isHardwareDetected(); verify(mFaceManager).hasEnrolledTemplates(anyInt()); } @@ -523,7 +523,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); } @Test @@ -533,7 +533,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test @@ -545,7 +546,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test @@ -568,13 +570,14 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); // Stop scanning when bouncer becomes visible setKeyguardBouncerVisibility(true); clearInvocations(mFaceManager); mKeyguardUpdateMonitor.requestFaceAuth(true); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test @@ -582,7 +585,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.setKeyguardOccluded(true); mKeyguardUpdateMonitor.setAssistantVisible(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); } @Test @@ -594,7 +597,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); } @Test @@ -604,7 +607,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test @@ -615,7 +619,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test @@ -626,7 +631,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); - verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); } @Test @@ -638,7 +643,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true); mTestableLooper.processAllMessages(); - verify(mFaceManager, never()).authenticate(any(), any(), any(), any()); + verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyBoolean()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java index 5cd781085b15..090cf9f63eaf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -50,7 +49,6 @@ import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -78,14 +76,16 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { @Mock private TextView mIndicatorView; @Mock private ImageView mIconView; @Mock private View mIconHolderView; - @Mock private AuthBiometricFaceView.IconController mIconController; + @Mock private AuthBiometricFaceView.IconController mFaceIconController; + @Mock private AuthBiometricFaceToFingerprintView.UdfpsIconController mUdfpsIconController; @Before public void setup() { MockitoAnnotations.initMocks(this); mFaceToFpView = new TestableView(mContext); - mFaceToFpView.mIconController = mIconController; + mFaceToFpView.mFaceIconController = mFaceIconController; + mFaceToFpView.mUdfpsIconController = mUdfpsIconController; mFaceToFpView.setCallback(mCallback); mFaceToFpView.mNegativeButton = mNegativeButton; @@ -99,20 +99,23 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { @Test public void testStateUpdated_whenDialogAnimatedIn() { mFaceToFpView.onDialogAnimatedIn(); - verify(mFaceToFpView.mIconController) + verify(mFaceToFpView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING)); + verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt()); } @Test public void testIconUpdatesState_whenDialogStateUpdated() { mFaceToFpView.onDialogAnimatedIn(); - verify(mFaceToFpView.mIconController) + verify(mFaceToFpView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING)); + verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt()); mFaceToFpView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED); - verify(mFaceToFpView.mIconController).updateState( + verify(mFaceToFpView.mFaceIconController).updateState( eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED)); + verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt()); assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED, mFaceToFpView.mState); } @@ -120,21 +123,22 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { @Test public void testStateUpdated_whenSwitchToFingerprint() { mFaceToFpView.onDialogAnimatedIn(); - verify(mFaceToFpView.mIconController) + verify(mFaceToFpView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING)); mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR); - mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING); - InOrder order = inOrder(mFaceToFpView.mIconController); - order.verify(mFaceToFpView.mIconController).updateState( + verify(mFaceToFpView.mFaceIconController).deactivate(); + verify(mFaceToFpView.mUdfpsIconController).updateState( eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING), eq(AuthBiometricFaceToFingerprintView.STATE_ERROR)); - order.verify(mFaceToFpView.mIconController).updateState( + verify(mConfirmButton).setVisibility(eq(View.GONE)); + + mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING); + + verify(mFaceToFpView.mUdfpsIconController).updateState( eq(AuthBiometricFaceToFingerprintView.STATE_ERROR), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING)); - - verify(mConfirmButton).setVisibility(eq(View.GONE)); } @Test @@ -172,7 +176,10 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead))); verify(mCallback).onAction( eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR)); - assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING, mFaceToFpView.mState); + + // First we enter the error state, since we need to show the error animation/text. The + // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING. + assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState); } @Test @@ -185,13 +192,16 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead))); verify(mCallback).onAction( eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR)); - assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING, mFaceToFpView.mState); + + // First we enter the error state, since we need to show the error animation/text. The + // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING. + assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState); } @Test public void testFingerprintOnlyStartsOnFirstError() { mFaceToFpView.onDialogAnimatedIn(); - verify(mFaceToFpView.mIconController) + verify(mFaceToFpView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING)); mFaceToFpView.onDialogAnimatedIn(); @@ -260,11 +270,6 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase { protected int getDelayAfterAuthenticatedDurationMs() { return 0; } - - @Override - protected IconController createUdfpsIconController() { - return AuthBiometricFaceToFingerprintViewTest.this.mIconController; - } } private class MockInjector extends AuthBiometricView.Injector { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java index 043bd5cd6ba5..b93381d2b5c9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java @@ -62,7 +62,7 @@ public class AuthBiometricFaceViewTest extends SysuiTestCase { public void setup() { MockitoAnnotations.initMocks(this); mFaceView = new TestableFaceView(mContext); - mFaceView.mIconController = mock(TestableFaceView.TestableIconController.class); + mFaceView.mFaceIconController = mock(TestableFaceView.TestableIconController.class); mFaceView.setCallback(mCallback); mFaceView.mNegativeButton = mNegativeButton; @@ -78,18 +78,18 @@ public class AuthBiometricFaceViewTest extends SysuiTestCase { @Test public void testStateUpdated_whenDialogAnimatedIn() { mFaceView.onDialogAnimatedIn(); - verify(mFaceView.mIconController) + verify(mFaceView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING)); } @Test public void testIconUpdatesState_whenDialogStateUpdated() { mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATING); - verify(mFaceView.mIconController) + verify(mFaceView.mFaceIconController) .updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING)); mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED); - verify(mFaceView.mIconController).updateState( + verify(mFaceView.mFaceIconController).updateState( eq(AuthBiometricFaceView.STATE_AUTHENTICATING), eq(AuthBiometricFaceView.STATE_AUTHENTICATED)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index ca114516ef8d..2120b0ee4790 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -62,6 +63,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.Execution; import com.android.systemui.util.concurrency.FakeExecution; @@ -143,6 +145,8 @@ public class UdfpsControllerTest extends SysuiTestCase { private DisplayManager mDisplayManager; @Mock private Handler mHandler; + @Mock + private ConfigurationController mConfigurationController; private FakeExecutor mFgExecutor; @@ -150,6 +154,10 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private UdfpsView mUdfpsView; @Mock + private UdfpsEnrollView mEnrollView; + @Mock + private UdfpsKeyguardView mKeyguardView; + @Mock private UdfpsKeyguardViewController mUdfpsKeyguardViewController; @Mock private TypedArray mBrightnessValues; @@ -171,7 +179,13 @@ public class UdfpsControllerTest extends SysuiTestCase { setUpResources(); mExecution = new FakeExecution(); - when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)).thenReturn(mUdfpsView); + when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)) + .thenReturn(mUdfpsView); + when(mLayoutInflater.inflate(R.layout.udfps_enroll_view, null)) + .thenReturn(mEnrollView); // for showOverlay REASON_ENROLL_ENROLLING + when(mLayoutInflater.inflate(R.layout.udfps_keyguard_view, null)) + .thenReturn(mKeyguardView); // for showOverlay REASON_AUTH_FPM_KEYGUARD + when(mEnrollView.getContext()).thenReturn(mContext); final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>(); final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); @@ -214,7 +228,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mKeyguardStateController, mKeyguardBypassController, mDisplayManager, - mHandler); + mHandler, + mConfigurationController); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); @@ -264,6 +279,75 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test + public void onActionMove_dozing_setDeviceEntryIntent() throws RemoteException { + // GIVEN the current animation is UdfpsKeyguardViewController and device IS dozing + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController); + when(mStatusBarStateController.isDozing()).thenReturn(true); + + // GIVEN that the overlay is showing + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // WHEN ACTION_DOWN is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + moveEvent.recycle(); + + // THEN device entry intent is never to true b/c device was dozing on touch + verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(true); + } + + @Test + public void onActionMove_onKeyguard_setDeviceEntryIntent() throws RemoteException { + // GIVEN the current animation is UdfpsKeyguardViewController and device isn't dozing + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController); + when(mStatusBarStateController.isDozing()).thenReturn(false); + + // GIVEN that the overlay is showing + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // WHEN ACTION_DOWN is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + moveEvent.recycle(); + + // THEN device entry intent is set to true + verify(mKeyguardBypassController).setUserHasDeviceEntryIntent(true); + } + + @Test + public void onActionMove_onEnrollment_neverSetDeviceEntryIntent() throws RemoteException { + // GIVEN the current animation is UdfpsEnrollViewController + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + when(mUdfpsView.getAnimationViewController()).thenReturn( + mock(UdfpsEnrollViewController.class)); + + // GIVEN that the overlay is showing + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, + IUdfpsOverlayController.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // WHEN ACTION_DOWN is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + moveEvent.recycle(); + + // THEN device entry intent is never set + verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(anyBoolean()); + } + + @Test public void onActionMoveTouch_whenCanDismissLockScreen_entersDevice() throws RemoteException { // GIVEN can dismiss lock screen and the current animation is an UdfpsKeyguardViewController when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java index f62587c6e87c..0c03a51f816e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.concurrency.DelayableExecutor; import org.junit.Before; @@ -76,6 +77,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { @Mock private KeyguardViewMediator mKeyguardViewMediator; @Mock + private ConfigurationController mConfigurationController; + @Mock private UdfpsController mUdfpsController; private UdfpsKeyguardViewController mController; @@ -110,6 +113,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { mDumpManager, mKeyguardViewMediator, mLockscreenShadeTransitionController, + mConfigurationController, mUdfpsController); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 1dacc6245d84..ad0878031679 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -33,8 +34,9 @@ import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; import android.os.PowerManager; import android.os.PowerManager.WakeLock; +import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper.RunWithLooper; +import android.testing.TestableLooper; import androidx.test.filters.SmallTest; @@ -65,7 +67,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) -@RunWithLooper +@TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest public class KeyguardViewMediatorTest extends SysuiTestCase { private KeyguardViewMediator mViewMediator; @@ -124,6 +126,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mUnlockedScreenOffAnimationController, () -> mNotificationShadeDepthController); mViewMediator.start(); + mViewMediator.onSystemReady(); } @Test @@ -160,4 +163,27 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onDozeAmountChanged(1f, 1f); assertFalse(mViewMediator.isAnimatingScreenOff()); } + + @Test + public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway() { + // When showing and provisioned + when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true); + mViewMediator.setShowingLocked(true); + + // and a SIM becomes locked and requires a PIN + mViewMediator.mUpdateCallback.onSimStateChanged( + 1 /* subId */, + 0 /* slotId */, + TelephonyManager.SIM_STATE_PIN_REQUIRED); + + // and the keyguard goes away + mViewMediator.setShowingLocked(false); + when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false); + mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false); + + TestableLooper.get(this).processAllMessages(); + + // then make sure it comes back + verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index c1a7bc5f8bf5..3ee3e55c749a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -190,6 +190,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { mBypassController, mQsComponentFactory, mFeatureFlags, - mFalsingManager); + mFalsingManager, + mock(DumpManager.class)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt new file mode 100644 index 000000000000..56f2905e834f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2021 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.systemui.qs + +import com.google.common.truth.Truth.assertThat + +import androidx.test.filters.SmallTest + +import android.testing.AndroidTestingRunner +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.children +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class QSPanelSwitchToParentTest : SysuiTestCase() { + + private lateinit var parent1: FrameLayout + private lateinit var parent2: FrameLayout + + private lateinit var movingView: View + + private lateinit var view1A: View + private lateinit var view1B: View + private lateinit var view1C: View + + private lateinit var view2A: View + private lateinit var view2B: View + private lateinit var view2C: View + + @Before + fun setUp() { + parent1 = FrameLayout(mContext) + parent2 = FrameLayout(mContext) + + movingView = View(mContext) + + view1A = View(mContext) + parent1.addView(view1A) + view1B = View(mContext) + parent1.addView(view1B) + view1C = View(mContext) + parent1.addView(view1C) + + view2A = View(mContext) + parent2.addView(view2A) + view2B = View(mContext) + parent2.addView(view2B) + view2C = View(mContext) + parent2.addView(view2C) + } + + @Test + fun testNullTargetNoInteractions() { + QSPanel.switchToParent(movingView, null, -1, "") + + assertThat(movingView.parent).isNull() + } + + @Test + fun testMoveToEndNoParent() { + QSPanel.switchToParent(movingView, parent2, -1, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + + assertThat(parent2.childrenList).containsExactly( + view2A, view2B, view2C, movingView + ) + } + + @Test + fun testMoveToEndDifferentParent() { + parent1.addView(movingView, 0) + + QSPanel.switchToParent(movingView, parent2, -1, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + assertThat(parent2.childrenList).containsExactly( + view2A, view2B, view2C, movingView + ) + } + + @Test + fun testMoveToEndSameParent() { + parent2.addView(movingView, 0) + + QSPanel.switchToParent(movingView, parent2, -1, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + assertThat(parent2.childrenList).containsExactly( + view2A, view2B, view2C, movingView + ) + } + + @Test + fun testMoveToMiddleFromNoParent() { + QSPanel.switchToParent(movingView, parent2, 1, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + assertThat(parent2.childrenList).containsExactly( + view2A, movingView, view2B, view2C + ) + } + + @Test + fun testMoveToMiddleDifferentParent() { + parent1.addView(movingView, 1) + + QSPanel.switchToParent(movingView, parent2, 2, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + assertThat(parent2.childrenList).containsExactly( + view2A, view2B, movingView, view2C + ) + } + + @Test + fun testMoveToMiddleSameParent() { + parent2.addView(movingView, 0) + + QSPanel.switchToParent(movingView, parent2, 1, "") + + assertThat(parent1.childrenList).containsExactly( + view1A, view1B, view1C + ) + assertThat(parent2.childrenList).containsExactly( + view2A, movingView, view2B, view2C + ) + } + + private val ViewGroup.childrenList: List<View> + get() = children.toList() +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java index 4f8859927d06..16d4dddd67aa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -14,6 +14,8 @@ package com.android.systemui.qs; +import static junit.framework.Assert.assertEquals; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -21,19 +23,20 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.res.Configuration; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTileView; -import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.util.animation.UniqueObjectHostView; import org.junit.Before; import org.junit.Test; @@ -56,29 +59,28 @@ public class QSPanelTest extends SysuiTestCase { private QSTileImpl dndTile; @Mock private QSPanelControllerBase.TileRecord mDndTileRecord; - @Mock - private QSLogger mQSLogger; private ViewGroup mParentView; @Mock private QSDetail.Callback mCallback; @Mock private QSTileView mQSTileView; + + private UniqueObjectHostView mMediaView; + private View mSecurityFooter; @Mock - private ActivityStarter mActivityStarter; + private FrameLayout mHeaderContainer; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); -// // Dependencies for QSSecurityFooter -// mDependency.injectTestDependency(ActivityStarter.class, mActivityStarter); -// mDependency.injectMockDependency(SecurityController.class); -// mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); -// mContext.addMockSystemService(Context.USER_SERVICE, mock(UserManager.class)); mDndTileRecord.tile = dndTile; mDndTileRecord.tileView = mQSTileView; + mMediaView = new UniqueObjectHostView(mContext); + mSecurityFooter = new View(mContext); + mTestableLooper.runWithLooper(() -> { mQsPanel = new QSPanel(mContext, null); mQsPanel.initialize(); @@ -92,6 +94,7 @@ public class QSPanelTest extends SysuiTestCase { when(mHost.createTileView(any(), any(), anyBoolean())).thenReturn(mQSTileView); mQsPanel.addTile(mDndTileRecord); mQsPanel.setCallback(mCallback); + mQsPanel.setHeaderContainer(mHeaderContainer); }); } @@ -112,4 +115,62 @@ public class QSPanelTest extends SysuiTestCase { verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt()); } + + @Test + public void testSecurityFooterAtEndNoMedia_portrait() { + mTestableLooper.processAllMessages(); + + mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; + + mQsPanel.setSecurityFooter(mSecurityFooter); + + int children = mQsPanel.getChildCount(); + assertEquals(children - 1, mQsPanel.indexOfChild(mSecurityFooter)); + } + + @Test + public void testSecurityFooterRightBeforeMedia_portrait() { + mTestableLooper.processAllMessages(); + + mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; + + mQsPanel.addView(mMediaView); + + mQsPanel.setSecurityFooter(mSecurityFooter); + + int securityFooterIndex = mQsPanel.indexOfChild(mSecurityFooter); + int mediaIndex = mQsPanel.indexOfChild(mMediaView); + + assertEquals(mediaIndex - 1, securityFooterIndex); + } + + @Test + public void testSecurityFooterRightBeforeMedia_portrait_configChange() { + mTestableLooper.processAllMessages(); + + mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; + + mQsPanel.addView(mMediaView); + + mQsPanel.setSecurityFooter(mSecurityFooter); + + mQsPanel.onConfigurationChanged(mContext.getResources().getConfiguration()); + + int securityFooterIndex = mQsPanel.indexOfChild(mSecurityFooter); + int mediaIndex = mQsPanel.indexOfChild(mMediaView); + + assertEquals(mediaIndex - 1, securityFooterIndex); + } + + @Test + public void testSecurityFooterInHeader_landscape() { + mTestableLooper.processAllMessages(); + + mContext.getResources().getConfiguration().orientation = + Configuration.ORIENTATION_LANDSCAPE; + + mQsPanel.setSecurityFooter(mSecurityFooter); + + verify(mHeaderContainer).addView(mSecurityFooter, 0); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java index 3a4bc699b967..670a130d610a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java @@ -26,7 +26,6 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; -import android.content.Context; import android.graphics.Rect; import android.os.RemoteException; import android.testing.AndroidTestingRunner; @@ -36,7 +35,6 @@ import android.view.IWindowManager; import android.view.ScrollCaptureResponse; import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; import com.android.systemui.SysuiTestCase; import com.android.systemui.screenshot.ScrollCaptureClient.CaptureResult; @@ -83,7 +81,7 @@ public class ScrollCaptureClientTest extends SysuiTestCase { /* taskId */ anyInt(), any(IScrollCaptureResponseListener.class)); // Create client - ScrollCaptureClient client = new ScrollCaptureClient(mContext, mWm); + ScrollCaptureClient client = new ScrollCaptureClient(mWm, Runnable::run, mContext); // Request scroll capture ListenableFuture<ScrollCaptureResponse> requestFuture = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt new file mode 100644 index 000000000000..ace2c71d9c63 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2021 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.systemui.statusbar.policy + +import android.app.IActivityTaskManager +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.UserInfo +import android.graphics.Bitmap +import android.hardware.face.FaceManager +import android.hardware.fingerprint.FingerprintManager +import android.os.Handler +import android.os.UserHandle +import android.os.UserManager +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.internal.util.UserIcons +import com.android.systemui.GuestResumeSessionReceiver +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.qs.QSUserSwitcherEvent +import com.android.systemui.settings.UserTracker +import com.android.systemui.telephony.TelephonyListenerManager +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.settings.SecureSettings +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.eq +import org.mockito.Mock +import org.mockito.Mockito.any +import org.mockito.Mockito.anyString +import org.mockito.Mockito.mock +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +@SmallTest +class UserSwitcherControllerTest : SysuiTestCase() { + @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var handler: Handler + @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var userManager: UserManager + @Mock private lateinit var activityStarter: ActivityStarter + @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher + @Mock private lateinit var activityTaskManager: IActivityTaskManager + @Mock private lateinit var userDetailAdapter: UserSwitcherController.UserDetailAdapter + @Mock private lateinit var telephonyListenerManager: TelephonyListenerManager + @Mock private lateinit var secureSettings: SecureSettings + @Mock private lateinit var falsingManager: FalsingManager + private lateinit var testableLooper: TestableLooper + private lateinit var uiBgExecutor: FakeExecutor + private lateinit var uiEventLogger: UiEventLoggerFake + private lateinit var userSwitcherController: UserSwitcherController + private lateinit var picture: Bitmap + private val ownerId = UserHandle.USER_SYSTEM + private val ownerInfo = UserInfo(ownerId, "Owner", null, + UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL or UserInfo.FLAG_INITIALIZED or + UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM, + UserManager.USER_TYPE_FULL_SYSTEM) + private val guestId = 1234 + private val guestInfo = UserInfo(guestId, "Guest", null, + UserInfo.FLAG_FULL or UserInfo.FLAG_GUEST, UserManager.USER_TYPE_FULL_GUEST) + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + testableLooper = TestableLooper.get(this) + uiBgExecutor = FakeExecutor(FakeSystemClock()) + uiEventLogger = UiEventLoggerFake() + + context.orCreateTestableResources.addOverride( + com.android.internal.R.bool.config_guestUserAutoCreated, false) + + context.addMockSystemService(Context.FACE_SERVICE, mock(FaceManager::class.java)) + context.addMockSystemService(Context.FINGERPRINT_SERVICE, + mock(FingerprintManager::class.java)) + + `when`(userManager.canAddMoreUsers()).thenReturn(true) + + userSwitcherController = UserSwitcherController(context, + userManager, + userTracker, + keyguardStateController, + handler, + activityStarter, + broadcastDispatcher, + uiEventLogger, + falsingManager, + telephonyListenerManager, + activityTaskManager, + userDetailAdapter, + secureSettings, + uiBgExecutor) + userSwitcherController.mPauseRefreshUsers = true + + picture = UserIcons.convertToBitmap(context.getDrawable(R.drawable.ic_avatar_user)) + } + + @Test + fun testAddGuest_okButtonPressed_isLogged() { + val emptyGuestUserRecord = UserSwitcherController.UserRecord( + null, + null, + true /* guest */, + false /* current */, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) + `when`(userTracker.userId).thenReturn(ownerId) + `when`(userTracker.userInfo).thenReturn(ownerInfo) + + `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo) + + userSwitcherController.onUserListItemClicked(emptyGuestUserRecord) + testableLooper.processAllMessages() + assertEquals(1, uiEventLogger.numLogs()) + assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_ADD.id, uiEventLogger.eventId(0)) + } + + @Test + fun testRemoveGuest_removeButtonPressed_isLogged() { + val currentGuestUserRecord = UserSwitcherController.UserRecord( + guestInfo, + picture, + true /* guest */, + true /* current */, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) + `when`(userTracker.userId).thenReturn(guestInfo.id) + `when`(userTracker.userInfo).thenReturn(guestInfo) + + userSwitcherController.onUserListItemClicked(currentGuestUserRecord) + assertNotNull(userSwitcherController.mExitGuestDialog) + userSwitcherController.mExitGuestDialog + .getButton(DialogInterface.BUTTON_POSITIVE).performClick() + testableLooper.processAllMessages() + assertEquals(1, uiEventLogger.numLogs()) + assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id, uiEventLogger.eventId(0)) + } + + @Test + fun testRemoveGuest_cancelButtonPressed_isNotLogged() { + val currentGuestUserRecord = UserSwitcherController.UserRecord( + guestInfo, + picture, + true /* guest */, + true /* current */, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) + `when`(userTracker.userId).thenReturn(guestId) + `when`(userTracker.userInfo).thenReturn(guestInfo) + + userSwitcherController.onUserListItemClicked(currentGuestUserRecord) + assertNotNull(userSwitcherController.mExitGuestDialog) + userSwitcherController.mExitGuestDialog + .getButton(DialogInterface.BUTTON_NEGATIVE).performClick() + testableLooper.processAllMessages() + assertEquals(0, uiEventLogger.numLogs()) + } + + @Test + fun testWipeGuest_startOverButtonPressed_isLogged() { + val currentGuestUserRecord = UserSwitcherController.UserRecord( + guestInfo, + picture, + true /* guest */, + false /* current */, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) + `when`(userTracker.userId).thenReturn(guestId) + `when`(userTracker.userInfo).thenReturn(guestInfo) + + // Simulate that guest user has already logged in + `when`(secureSettings.getIntForUser( + eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt())) + .thenReturn(1) + + userSwitcherController.onUserListItemClicked(currentGuestUserRecord) + + // Simulate a user switch event + val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId) + + assertNotNull(userSwitcherController.mGuestResumeSessionReceiver) + userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent) + + assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog) + userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog + .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_WIPE).performClick() + testableLooper.processAllMessages() + assertEquals(1, uiEventLogger.numLogs()) + assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_WIPE.id, uiEventLogger.eventId(0)) + } + + @Test + fun testWipeGuest_continueButtonPressed_isLogged() { + val currentGuestUserRecord = UserSwitcherController.UserRecord( + guestInfo, + picture, + true /* guest */, + false /* current */, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) + `when`(userTracker.userId).thenReturn(guestId) + `when`(userTracker.userInfo).thenReturn(guestInfo) + + // Simulate that guest user has already logged in + `when`(secureSettings.getIntForUser( + eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt())) + .thenReturn(1) + + userSwitcherController.onUserListItemClicked(currentGuestUserRecord) + + // Simulate a user switch event + val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId) + + assertNotNull(userSwitcherController.mGuestResumeSessionReceiver) + userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent) + + assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog) + userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog + .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_DONTWIPE) + .performClick() + testableLooper.processAllMessages() + assertEquals(1, uiEventLogger.numLogs()) + assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_CONTINUE.id, uiEventLogger.eventId(0)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java index 8f0754592b83..cc2afe2f7b8a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java @@ -60,6 +60,25 @@ public class ProximitySensorDualTest extends SysuiTestCase { } @Test + public void testPrimaryBelowDoesNotInvokeSecondary() { + TestableListener listener = new TestableListener(); + + mProximitySensor.register(listener); + assertTrue(mProximitySensor.isRegistered()); + assertFalse(mThresholdSensorPrimary.isPaused()); + assertTrue(mThresholdSensorSecondary.isPaused()); + assertNull(listener.mLastEvent); + assertEquals(0, listener.mCallCount); + + // Trigger primary sensor. Our secondary sensor is not registered. + mThresholdSensorPrimary.triggerEvent(false, 0); + assertFalse(mThresholdSensorPrimary.isPaused()); + assertTrue(mThresholdSensorSecondary.isPaused()); + assertNull(listener.mLastEvent); + assertEquals(0, listener.mCallCount); + } + + @Test public void testSingleListener() { TestableListener listener = new TestableListener(); @@ -256,40 +275,6 @@ public class ProximitySensorDualTest extends SysuiTestCase { } @Test - public void testPrimaryCancelsSecondary() { - TestableListener listener = new TestableListener(); - - mProximitySensor.register(listener); - assertFalse(mThresholdSensorPrimary.isPaused()); - assertTrue(mThresholdSensorSecondary.isPaused()); - assertNull(listener.mLastEvent); - assertEquals(0, listener.mCallCount); - - mThresholdSensorPrimary.triggerEvent(true, 0); - assertNull(listener.mLastEvent); - assertEquals(0, listener.mCallCount); - mThresholdSensorSecondary.triggerEvent(true, 0); - assertTrue(listener.mLastEvent.getBelow()); - assertEquals(1, listener.mCallCount); - - // When the primary reports false, the secondary is no longer needed. We get an immediate - // report. - mThresholdSensorPrimary.triggerEvent(false, 1); - assertFalse(listener.mLastEvent.getBelow()); - assertEquals(2, listener.mCallCount); - - // The secondary is now ignored. No more work is scheduled. - mFakeExecutor.advanceClockToNext(); - mFakeExecutor.runNextReady(); - mThresholdSensorSecondary.triggerEvent(true, 0); - assertFalse(listener.mLastEvent.getBelow()); - assertEquals(2, listener.mCallCount); - assertEquals(0, mFakeExecutor.numPending()); - - mProximitySensor.unregister(listener); - } - - @Test public void testSecondaryCancelsSecondary() { TestableListener listener = new TestableListener(); ThresholdSensor.Listener cancelingListener = new ThresholdSensor.Listener() { @@ -342,7 +327,7 @@ public class ProximitySensorDualTest extends SysuiTestCase { // The secondary sensor should now remain resumed indefinitely. assertFalse(mThresholdSensorSecondary.isPaused()); - mThresholdSensorPrimary.triggerEvent(false, 1); + mThresholdSensorSecondary.triggerEvent(false, 1); assertFalse(listener.mLastEvent.getBelow()); assertEquals(2, listener.mCallCount); diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 5aec6aa99c12..a56b1db1494c 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -3285,6 +3285,57 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } + private void applyResourceOverlaysToWidgetsLocked(Set<String> packageNames, int userId, + boolean updateFrameworkRes) { + for (int i = 0, N = mProviders.size(); i < N; i++) { + Provider provider = mProviders.get(i); + if (provider.getUserId() != userId) { + continue; + } + + final String packageName = provider.id.componentName.getPackageName(); + if (!updateFrameworkRes && !packageNames.contains(packageName)) { + continue; + } + + ApplicationInfo newAppInfo = null; + try { + newAppInfo = mPackageManager.getApplicationInfo(packageName, + PackageManager.GET_SHARED_LIBRARY_FILES, userId); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to retrieve app info for " + packageName + + " userId=" + userId, e); + } + if (newAppInfo == null) { + continue; + } + ApplicationInfo oldAppInfo = provider.info.providerInfo.applicationInfo; + if (!newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) { + // Overlay paths are generated against a particular version of an application. + // The overlays paths of a newly upgraded application are incompatible with the + // old version of the application. + continue; + } + + // Isolate the changes relating to RROs. The app info must be copied to prevent + // affecting other parts of system server that may have cached this app info. + oldAppInfo = new ApplicationInfo(oldAppInfo); + oldAppInfo.overlayPaths = newAppInfo.overlayPaths.clone(); + oldAppInfo.resourceDirs = newAppInfo.resourceDirs.clone(); + provider.info.providerInfo.applicationInfo = oldAppInfo; + + for (int j = 0, M = provider.widgets.size(); j < M; j++) { + Widget widget = provider.widgets.get(j); + if (widget.views != null) { + widget.views.updateAppInfo(oldAppInfo); + } + if (widget.maskedViews != null) { + widget.maskedViews.updateAppInfo(oldAppInfo); + } + } + } + } + /** * Updates all providers with the specified package names, and records any providers that were * pruned. @@ -4875,5 +4926,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku public void unlockUser(int userId) { handleUserUnlocked(userId); } + + @Override + public void applyResourceOverlaysToWidgets(Set<String> packageNames, int userId, + boolean updateFrameworkRes) { + synchronized (mLock) { + applyResourceOverlaysToWidgetsLocked(new HashSet<>(packageNames), userId, + updateFrameworkRes); + } + } } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 078d908684bc..df269d71f915 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -96,6 +96,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.TimeUtils; import android.view.KeyEvent; +import android.view.accessibility.AccessibilityManager; import android.view.autofill.AutofillId; import android.view.autofill.AutofillManager; import android.view.autofill.AutofillManager.SmartSuggestionMode; @@ -346,6 +347,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl(); + private final AccessibilityManager mAccessibilityManager; + void onSwitchInputMethodLocked() { // One caveat is that for the case where the focus is on a field for which regular autofill // returns null, and augmented autofill is triggered, and then the user switches the input @@ -440,6 +443,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (!mWaitForInlineRequest || mPendingInlineSuggestionsRequest != null) { return; } + mWaitForInlineRequest = inlineSuggestionsRequest != null; mPendingInlineSuggestionsRequest = inlineSuggestionsRequest; maybeRequestFillLocked(); viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST); @@ -457,9 +461,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } - mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(), - mPendingFillRequest.getFillContexts(), mPendingFillRequest.getClientState(), - mPendingFillRequest.getFlags(), mPendingInlineSuggestionsRequest); + // If a11y touch exploration is enabled, then we do not send an inline fill request + // to the regular af service, because dropdown UI is easier to use. + if (!mAccessibilityManager.isTouchExplorationEnabled()) { + mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(), + mPendingFillRequest.getFillContexts(), + mPendingFillRequest.getClientState(), + mPendingFillRequest.getFlags(), mPendingInlineSuggestionsRequest); + } } mRemoteFillService.onFillRequest(mPendingFillRequest); @@ -888,6 +897,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mRemoteFillService = serviceComponentName == null ? null : new RemoteFillService(context, serviceComponentName, userId, this, bindInstantServiceAllowed); + mAccessibilityManager = AccessibilityManager.getInstance(context); mActivityToken = activityToken; mHasCallback = hasCallback; mUiLatencyHistory = uiLatencyHistory; diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index b7feb6306c99..30de4b416410 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -17,6 +17,7 @@ package com.android.server.companion; +import static android.Manifest.permission.BIND_COMPANION_DEVICE_SERVICE; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED; import static android.content.Context.BIND_IMPORTANT; @@ -1197,6 +1198,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind + " has " + packageResolveInfos.size()); return new ServiceConnector.NoOp<>(); } + String servicePermission = packageResolveInfos.get(0).serviceInfo.permission; + if (!BIND_COMPANION_DEVICE_SERVICE.equals(servicePermission)) { + Slog.w(LOG_TAG, "Binding CompanionDeviceService must have " + + BIND_COMPANION_DEVICE_SERVICE + " permission."); + return new ServiceConnector.NoOp<>(); + } ComponentName componentName = packageResolveInfos.get(0).serviceInfo.getComponentName(); Slog.i(LOG_TAG, "Initializing CompanionDeviceService binding for " + componentName); return new ServiceConnector.Impl<ICompanionDeviceService>(getContext(), diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 25ea12b1c341..8a42ddfdc19d 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -70,6 +70,7 @@ import android.provider.Settings; import android.service.contentcapture.ActivityEvent.ActivityEventType; import android.service.contentcapture.IDataShareCallback; import android.service.contentcapture.IDataShareReadAdapter; +import android.service.voice.VoiceInteractionManagerInternal; import android.util.ArraySet; import android.util.LocalLog; import android.util.Pair; @@ -302,6 +303,37 @@ public final class ContentCaptureManagerService extends || super.isDisabledLocked(userId); } + @Override + protected void assertCalledByPackageOwner(@NonNull String packageName) { + try { + super.assertCalledByPackageOwner(packageName); + } catch (SecurityException e) { + final int callingUid = Binder.getCallingUid(); + + VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity + hotwordDetectionServiceIdentity = + LocalServices.getService(VoiceInteractionManagerInternal.class) + .getHotwordDetectionServiceIdentity(); + + if (callingUid != hotwordDetectionServiceIdentity.getIsolatedUid()) { + super.assertCalledByPackageOwner(packageName); + return; + } + + final String[] packages = + getContext() + .getPackageManager() + .getPackagesForUid(hotwordDetectionServiceIdentity.getOwnerUid()); + if (packages != null) { + for (String candidate : packages) { + if (packageName.equals(candidate)) return; // Found it + } + } + + throw e; + } + } + private boolean isDisabledBySettingsLocked(@UserIdInt int userId) { return mDisabledBySettings != null && mDisabledBySettings.get(userId); } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 225a8d48114b..904def0af2cf 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -57,6 +57,7 @@ import android.service.contentcapture.FlushMetrics; import android.service.contentcapture.IContentCaptureServiceCallback; import android.service.contentcapture.IDataShareCallback; import android.service.contentcapture.SnapshotData; +import android.service.voice.VoiceInteractionManagerInternal; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -415,12 +416,25 @@ final class ContentCapturePerUserService } if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class) .hasRunningActivity(callingUid, packageName)) { - final String[] packages = pm.getPackagesForUid(callingUid); - final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; - Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid - + ") passed package (" + packageName + ") owned by UID " + packageUid); - throw new SecurityException("Invalid package: " + packageName); + VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity + hotwordDetectionServiceIdentity = + LocalServices.getService(VoiceInteractionManagerInternal.class) + .getHotwordDetectionServiceIdentity(); + + boolean isHotwordDetectionServiceCall = + hotwordDetectionServiceIdentity != null + && callingUid == hotwordDetectionServiceIdentity.getIsolatedUid() + && packageUid == hotwordDetectionServiceIdentity.getOwnerUid(); + + if (!isHotwordDetectionServiceCall) { + final String[] packages = pm.getPackagesForUid(callingUid); + final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; + Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid + + ") passed package (" + packageName + ") owned by UID " + packageUid); + + throw new SecurityException("Invalid package: " + packageName); + } } } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 85ff2be43be4..b7c61a0d25cf 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -2505,6 +2505,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null, getTempAllowlistBroadcastOptions()); } + private boolean isBleState(int state) { + switch (state) { + case BluetoothAdapter.STATE_BLE_ON: + case BluetoothAdapter.STATE_BLE_TURNING_ON: + case BluetoothAdapter.STATE_BLE_TURNING_OFF: + return true; + } + return false; + } + @RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, @@ -2527,8 +2537,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { sendBluetoothServiceDownCallback(); unbindAndFinish(); sendBleStateChanged(prevState, newState); - // Don't broadcast as it has already been broadcast before - isStandardBroadcast = false; + + /* Currently, the OFF intent is broadcasted externally only when we transition + * from TURNING_OFF to BLE_ON state. So if the previous state is a BLE state, + * we are guaranteed that the OFF intent has been broadcasted earlier and we + * can safely skip it. + * Conversely, if the previous state is not a BLE state, it indicates that some + * sort of crash has occurred, moving us directly to STATE_OFF without ever + * passing through BLE_ON. We should broadcast the OFF intent in this case. */ + isStandardBroadcast = !isBleState(prevState); } else if (!intermediate_off) { // connect to GattService @@ -2581,6 +2598,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // Show prevState of BLE_ON as OFF to standard users prevState = BluetoothAdapter.STATE_OFF; } + if (DBG) { + Slog.d(TAG, + "Sending State Change: " + BluetoothAdapter.nameForState(prevState) + " > " + + BluetoothAdapter.nameForState(newState)); + } Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 019e4ea207ef..40e63dac72ea 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -21,8 +21,6 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; import static android.app.ActivityManager.RunningServiceInfo; import static android.app.ActivityManager.RunningTaskInfo; -import static android.app.ActivityManager.getCurrentUser; -import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; @@ -383,17 +381,9 @@ public final class SensorPrivacyService extends SystemService { int sensor; if (result == MODE_IGNORED) { - if (code == OP_RECORD_AUDIO) { + if (code == OP_RECORD_AUDIO || code == OP_PHONE_CALL_MICROPHONE) { sensor = MICROPHONE; - } else if (code == OP_CAMERA) { - sensor = CAMERA; - } else { - return; - } - } else if (result == MODE_ALLOWED) { - if (code == OP_PHONE_CALL_MICROPHONE) { - sensor = MICROPHONE; - } else if (code == OP_PHONE_CALL_CAMERA) { + } else if (code == OP_CAMERA || code == OP_PHONE_CALL_CAMERA) { sensor = CAMERA; } else { return; @@ -718,6 +708,9 @@ public final class SensorPrivacyService extends SystemService { public void setIndividualSensorPrivacy(@UserIdInt int userId, @SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) { enforceManageSensorPrivacyPermission(); + if (userId == UserHandle.USER_CURRENT) { + userId = mCurrentUser; + } if (!canChangeIndividualSensorPrivacy(userId, sensor)) { return; } @@ -843,6 +836,9 @@ public final class SensorPrivacyService extends SystemService { public void setIndividualSensorPrivacyForProfileGroup(@UserIdInt int userId, @SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) { enforceManageSensorPrivacyPermission(); + if (userId == UserHandle.USER_CURRENT) { + userId = mCurrentUser; + } int parentId = mUserManagerInternal.getProfileParentId(userId); forAllUsers(userId2 -> { if (parentId == mUserManagerInternal.getProfileParentId(userId2)) { @@ -896,6 +892,9 @@ public final class SensorPrivacyService extends SystemService { @Override public boolean isIndividualSensorPrivacyEnabled(@UserIdInt int userId, int sensor) { enforceObserveSensorPrivacyPermission(); + if (userId == UserHandle.USER_CURRENT) { + userId = mCurrentUser; + } synchronized (mLock) { return isIndividualSensorPrivacyEnabledLocked(userId, sensor); } @@ -1213,6 +1212,9 @@ public final class SensorPrivacyService extends SystemService { public void suppressIndividualSensorPrivacyReminders(int userId, int sensor, IBinder token, boolean suppress) { enforceManageSensorPrivacyPermission(); + if (userId == UserHandle.USER_CURRENT) { + userId = mCurrentUser; + } Objects.requireNonNull(token); Pair<Integer, UserHandle> key = new Pair<>(sensor, UserHandle.of(userId)); @@ -1265,10 +1267,14 @@ public final class SensorPrivacyService extends SystemService { case MICROPHONE: mAppOpsManagerInternal.setGlobalRestriction(OP_RECORD_AUDIO, enabled, mAppOpsRestrictionToken); + mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_MICROPHONE, enabled, + mAppOpsRestrictionToken); break; case CAMERA: mAppOpsManagerInternal.setGlobalRestriction(OP_CAMERA, enabled, mAppOpsRestrictionToken); + mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_CAMERA, enabled, + mAppOpsRestrictionToken); break; } } @@ -1898,9 +1904,9 @@ public final class SensorPrivacyService extends SystemService { if (!mIsInEmergencyCall) { mIsInEmergencyCall = true; if (mSensorPrivacyServiceImpl - .isIndividualSensorPrivacyEnabled(getCurrentUser(), MICROPHONE)) { + .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE)) { mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked( - getCurrentUser(), OTHER, MICROPHONE, false); + mCurrentUser, OTHER, MICROPHONE, false); mMicUnmutedForEmergencyCall = true; } else { mMicUnmutedForEmergencyCall = false; @@ -1915,7 +1921,7 @@ public final class SensorPrivacyService extends SystemService { mIsInEmergencyCall = false; if (mMicUnmutedForEmergencyCall) { mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked( - getCurrentUser(), OTHER, MICROPHONE, true); + mCurrentUser, OTHER, MICROPHONE, true); mMicUnmutedForEmergencyCall = false; } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 99ae52c00995..e0df4b797fe5 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -193,6 +193,7 @@ import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetManagerInternal; import android.content.AttributionSource; import android.content.AutofillOptions; import android.content.BroadcastReceiver; @@ -16597,6 +16598,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (updateFrameworkRes) { ParsingPackageUtils.readConfigUseRoundIcon(null); } + + AppWidgetManagerInternal widgets = LocalServices.getService(AppWidgetManagerInternal.class); + if (widgets != null) { + widgets.applyResourceOverlaysToWidgets(new HashSet<>(packagesToUpdate), userId, + updateFrameworkRes); + } + mProcessList.updateApplicationInfoLOSP(packagesToUpdate, userId, updateFrameworkRes); if (updateFrameworkRes) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 9f41c8ba9626..ae14ca7b66bd 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -841,6 +841,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void noteEvent(final int code, final String name, final int uid) { enforceCallingPermission(); + if (name == null) { + // TODO(b/194733136): Replace with an IllegalArgumentException throw. + Slog.wtfStack(TAG, "noteEvent called with null name. code = " + code); + return; + } + synchronized (mLock) { final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 9dbb70757cf7..7c336d768006 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -41,6 +41,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.ProcLocksReader; import com.android.internal.util.FrameworkStatsLog; import com.android.server.ServiceThread; @@ -319,6 +320,7 @@ public final class CachedAppOptimizer { private int mPersistentCompactionCount; private int mBfgsCompactionCount; private final ProcessDependencies mProcessDependencies; + private final ProcLocksReader mProcLocksReader; public CachedAppOptimizer(ActivityManagerService am) { this(am, null, new DefaultProcessDependencies()); @@ -335,6 +337,7 @@ public final class CachedAppOptimizer { mProcessDependencies = processDependencies; mTestCallback = callback; mSettingsObserver = new SettingsContentObserver(); + mProcLocksReader = new ProcLocksReader(); } /** @@ -1312,7 +1315,7 @@ public final class CachedAppOptimizer { try { // pre-check for locks to avoid unnecessary freeze/unfreeze operations - if (Process.hasFileLocks(pid)) { + if (mProcLocksReader.hasFileLocks(pid)) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, not freezing"); } @@ -1399,7 +1402,7 @@ public final class CachedAppOptimizer { try { // post-check to prevent races - if (Process.hasFileLocks(pid)) { + if (mProcLocksReader.hasFileLocks(pid)) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, reverting freeze"); } diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java index ca3168161605..b07684c9a004 100644 --- a/services/core/java/com/android/server/am/PhantomProcessList.java +++ b/services/core/java/com/android/server/am/PhantomProcessList.java @@ -365,6 +365,9 @@ public final class PhantomProcessList { private int onPhantomProcessFdEvent(FileDescriptor fd, int events) { synchronized (mLock) { final PhantomProcessRecord proc = mPhantomProcessesPidFds.get(fd.getInt$()); + if (proc == null) { + return 0; + } if ((events & EVENT_INPUT) != 0) { proc.onProcDied(true); } else { diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 6b7787aad17e..b1d300cd838e 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -1103,9 +1103,13 @@ public class BiometricService extends SystemService { } public boolean isAdvancedCoexLogicEnabled(Context context) { - return (Build.IS_USERDEBUG || Build.IS_ENG) - && Settings.Secure.getInt(context.getContentResolver(), - CoexCoordinator.SETTING_ENABLE_NAME, 0) != 0; + return Settings.Secure.getInt(context.getContentResolver(), + CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0; + } + + public boolean isCoexFaceNonBypassHapticsDisabled(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0; } } @@ -1138,6 +1142,8 @@ public class BiometricService extends SystemService { // by default. CoexCoordinator coexCoordinator = CoexCoordinator.getInstance(); coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context)); + coexCoordinator.setFaceHapticDisabledWhenNonBypass( + injector.isCoexFaceNonBypassHapticsDisabled(context)); try { injector.getActivityManagerService().registerUserSwitchObserver( diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 6463e04a4ff6..f4327e8a104d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -54,12 +54,18 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public static final int STATE_NEW = 0; // Framework/HAL have started this operation public static final int STATE_STARTED = 1; - // Operation is started, but requires some user action (such as finger lift & re-touch) + // Operation is started, but requires some user action to start (such as finger lift & re-touch) public static final int STATE_STARTED_PAUSED = 2; + // Same as above, except auth was attempted (rejected, timed out, etc). + public static final int STATE_STARTED_PAUSED_ATTEMPTED = 3; // Done, errored, canceled, etc. HAL/framework are not running this sensor anymore. - public static final int STATE_STOPPED = 3; + public static final int STATE_STOPPED = 4; - @IntDef({STATE_NEW, STATE_STARTED, STATE_STARTED_PAUSED, STATE_STOPPED}) + @IntDef({STATE_NEW, + STATE_STARTED, + STATE_STARTED_PAUSED, + STATE_STARTED_PAUSED_ATTEMPTED, + STATE_STOPPED}) @interface State {} private final boolean mIsStrongBiometric; @@ -70,6 +76,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> private final LockoutTracker mLockoutTracker; private final boolean mIsRestricted; private final boolean mAllowBackgroundAuthentication; + private final boolean mIsKeyguardBypassEnabled; protected final long mOperationId; @@ -97,7 +104,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener, @NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication, - boolean shouldVibrate) { + boolean shouldVibrate, boolean isKeyguardBypassEnabled) { super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId, shouldVibrate, statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); @@ -110,6 +117,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mLockoutTracker = lockoutTracker; mIsRestricted = restricted; mAllowBackgroundAuthentication = allowBackgroundAuthentication; + mIsKeyguardBypassEnabled = isKeyguardBypassEnabled; } public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) { @@ -394,6 +402,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> return mState; } + /** + * @return true if the client supports bypass (e.g. passive auth such as face), and if it's + * enabled by the user. + */ + public boolean isKeyguardBypassEnabled() { + return mIsKeyguardBypassEnabled; + } + @Override public int getProtoEnum() { return BiometricsProto.CM_AUTHENTICATE; diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java index f732a147e4b7..a15ecada3cae 100644 --- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java +++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java @@ -26,7 +26,6 @@ import android.os.Handler; import android.os.Looper; import android.util.Slog; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.biometrics.sensors.BiometricScheduler.SensorType; import com.android.server.biometrics.sensors.fingerprint.Udfps; @@ -46,6 +45,8 @@ public class CoexCoordinator { private static final String TAG = "BiometricCoexCoordinator"; public static final String SETTING_ENABLE_NAME = "com.android.server.biometrics.sensors.CoexCoordinator.enable"; + public static final String FACE_HAPTIC_DISABLE = + "com.android.server.biometrics.sensors.CoexCoordinator.disable_face_haptics"; private static final boolean DEBUG = true; // Successful authentications should be used within this amount of time. @@ -145,6 +146,10 @@ public class CoexCoordinator { mAdvancedLogicEnabled = enabled; } + public void setFaceHapticDisabledWhenNonBypass(boolean disabled) { + mFaceHapticDisabledWhenNonBypass = disabled; + } + @VisibleForTesting void reset() { mClientMap.clear(); @@ -154,6 +159,7 @@ public class CoexCoordinator { private final Map<Integer, AuthenticationClient<?>> mClientMap; @VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths; private boolean mAdvancedLogicEnabled; + private boolean mFaceHapticDisabledWhenNonBypass; private final Handler mHandler; private CoexCoordinator() { @@ -226,7 +232,11 @@ public class CoexCoordinator { mSuccessfulAuths.add(new SuccessfulAuth(mHandler, mSuccessfulAuths, currentTimeMillis, SENSOR_TYPE_FACE, client, callback)); } else { - callback.sendHapticFeedback(); + if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) { + Slog.w(TAG, "Skipping face success haptic"); + } else { + callback.sendHapticFeedback(); + } callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */); callback.handleLifecycleAfterAuth(); } @@ -242,6 +252,11 @@ public class CoexCoordinator { callback.sendHapticFeedback(); callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */); callback.handleLifecycleAfterAuth(); + } else { + // Capacitive fingerprint sensor (or other) + callback.sendHapticFeedback(); + callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */); + callback.handleLifecycleAfterAuth(); } } } else { @@ -274,12 +289,23 @@ public class CoexCoordinator { // BiometricScheduler do not get stuck. Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps); callback.handleLifecycleAfterAuth(); - } else { - // UDFPS is not actively authenticating (finger not touching, already - // rejected, etc). + } else if (isUdfpsAuthAttempted(udfps)) { + // If UDFPS is STATE_STARTED_PAUSED (e.g. finger rejected but can still + // auth after pointer goes down, it means UDFPS encountered a rejection. In + // this case, we need to play the final reject haptic since face auth is + // also done now. callback.sendHapticFeedback(); callback.handleLifecycleAfterAuth(); } + else { + // UDFPS auth has never been attempted. + if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) { + Slog.w(TAG, "Skipping face reject haptic"); + } else { + callback.sendHapticFeedback(); + } + callback.handleLifecycleAfterAuth(); + } } else if (isCurrentUdfps(client)) { // Face should either be running, or have already finished SuccessfulAuth auth = popSuccessfulFaceAuthIfExists(currentTimeMillis); @@ -370,6 +396,13 @@ public class CoexCoordinator { return false; } + private static boolean isUdfpsAuthAttempted(@Nullable AuthenticationClient<?> client) { + if (client instanceof Udfps) { + return client.getState() == AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED; + } + return false; + } + private boolean isUnknownClient(@NonNull AuthenticationClient<?> client) { for (AuthenticationClient<?> c : mClientMap.values()) { if (c == client) { @@ -396,6 +429,7 @@ public class CoexCoordinator { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Enabled: ").append(mAdvancedLogicEnabled); + sb.append(", Face Haptic Disabled: ").append(mFaceHapticDisabledWhenNonBypass); sb.append(", Queue size: " ).append(mSuccessfulAuths.size()); for (SuccessfulAuth auth : mSuccessfulAuths) { sb.append(", Auth: ").append(auth.toString()); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 219e06358afb..12d6b08b8bcf 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -251,7 +251,8 @@ public class FaceService extends SystemService { @Override // Binder call public void authenticate(final IBinder token, final long operationId, int userId, - final IFaceServiceReceiver receiver, final String opPackageName) { + final IFaceServiceReceiver receiver, final String opPackageName, + boolean isKeyguardBypassEnabled) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); // TODO(b/152413782): If the sensor supports face detect and the device is encrypted or @@ -275,7 +276,7 @@ public class FaceService extends SystemService { provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, 0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName, restricted, - statsClient, isKeyguard); + statsClient, isKeyguard, isKeyguardBypassEnabled); } @Override // Binder call @@ -318,10 +319,12 @@ public class FaceService extends SystemService { return; } + final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients final boolean restricted = true; // BiometricPrompt is always restricted provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie, new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted, - BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication); + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication, + isKeyguardBypassEnabled); } @Override // Binder call diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java index 1d2ac3b3bfdc..93ab1b65edff 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java @@ -110,7 +110,7 @@ public interface ServiceProvider { void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, boolean restricted, int statsClient, - boolean allowBackgroundAuthentication); + boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled); void cancelAuthentication(int sensorId, @NonNull IBinder token); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java index 0c06b205f2da..f7fd8d0972f6 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java @@ -69,11 +69,13 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsClient, @NonNull UsageStats usageStats, - @NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication) { + @NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication, + boolean isKeyguardBypassEnabled) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */); + lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */, + isKeyguardBypassEnabled); mUsageStats = usageStats; mLockoutCache = lockoutCache; mNotificationManager = context.getSystemService(NotificationManager.class); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 5c24108dcded..718b9da968f5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -378,7 +378,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, boolean restricted, int statsClient, - boolean allowBackgroundAuthentication) { + boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) { mHandler.post(() -> { final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId); final FaceAuthenticationClient client = new FaceAuthenticationClient( @@ -386,7 +386,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient, mUsageStats, mSensors.get(sensorId).getLockoutCache(), - allowBackgroundAuthentication); + allowBackgroundAuthentication, isKeyguardBypassEnabled); scheduleForSensor(sensorId, client); }); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index da4ad863fdba..d05333db7532 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -622,7 +622,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver, @NonNull String opPackageName, boolean restricted, int statsClient, - boolean allowBackgroundAuthentication) { + boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -630,7 +630,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext, mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric, - statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication); + statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication, + isKeyguardBypassEnabled); mScheduler.scheduleClientMonitor(client); }); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java index 868f3795845a..c33b957223a4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java @@ -61,11 +61,13 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsClient, @NonNull LockoutTracker lockoutTracker, - @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication) { + @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication, + boolean isKeyguardBypassEnabled) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */); + lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */, + isKeyguardBypassEnabled); mUsageStats = usageStats; final Resources resources = getContext().getResources(); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index fb2f2ef6b14c..8835c1e02610 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -72,7 +72,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener, - lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */); + lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */, + false /* isKeyguardBypassEnabled */); mLockoutCache = lockoutCache; mUdfpsOverlayController = udfpsOverlayController; mSensorProps = sensorProps; @@ -113,7 +114,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp mState = STATE_STOPPED; UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); } else { - mState = STATE_STARTED_PAUSED; + mState = STATE_STARTED_PAUSED_ATTEMPTED; } } @@ -187,7 +188,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp public void onPointerUp() { try { mIsPointerDown = false; - mState = STATE_STARTED_PAUSED; + mState = STATE_STARTED_PAUSED_ATTEMPTED; mALSProbeCallback.getProbe().disable(); getFreshDaemon().onPointerUp(0 /* pointerId */); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java index 5c9a764f27da..83f1480f4611 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java @@ -71,7 +71,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener, - lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */); + lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */, + false /* isKeyguardBypassEnabled */); mLockoutFrameworkImpl = lockoutTracker; mUdfpsOverlayController = udfpsOverlayController; mSensorProps = sensorProps; @@ -111,7 +112,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi resetFailedAttempts(getTargetUserId()); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); } else { - mState = STATE_STARTED_PAUSED; + mState = STATE_STARTED_PAUSED_ATTEMPTED; final @LockoutTracker.LockoutMode int lockoutMode = mLockoutFrameworkImpl.getLockoutModeForUser(getTargetUserId()); if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { @@ -205,7 +206,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi @Override public void onPointerUp() { mIsPointerDown = false; - mState = STATE_STARTED_PAUSED; + mState = STATE_STARTED_PAUSED_ATTEMPTED; mALSProbeCallback.getProbe().disable(); UdfpsHelper.onFingerUp(getFreshDaemon()); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 7d06d6ea50fa..afd18894f531 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -3285,6 +3285,9 @@ public final class DisplayManagerService extends SystemService { synchronized (mSyncRoot) { final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); + if (display == null) { + return null; + } final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { return null; diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 59f536cc4c5d..110893765cbd 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -2342,7 +2342,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call try { // TODO(brightnessfloat): change BatteryStats to use float mBatteryStats.noteScreenBrightness(BrightnessSynchronizer.brightnessFloatToInt( - brightness, null)); + brightness)); } catch (RemoteException e) { // same process } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 24d29d320cf6..f953cc8c8a27 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -795,12 +795,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { mBacklightAdapter.setBacklight(sdrBacklight, sdrNits, backlight, nits); Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenBrightness", - BrightnessSynchronizer.brightnessFloatToInt( - brightnessState, null)); + BrightnessSynchronizer.brightnessFloatToInt(brightnessState)); Trace.traceCounter(Trace.TRACE_TAG_POWER, "SdrScreenBrightness", BrightnessSynchronizer.brightnessFloatToInt( - sdrBrightnessState, null)); + sdrBrightnessState)); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 016c5ed36f5f..14616754e160 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -744,7 +744,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * * @throws SecurityException when it's not... */ - protected final void assertCalledByPackageOwner(@NonNull String packageName) { + protected void assertCalledByPackageOwner(@NonNull String packageName) { Objects.requireNonNull(packageName); final int uid = Binder.getCallingUid(); final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 9fcc9a1b7994..6fb9e58a49d1 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -3230,7 +3230,7 @@ public class InputManagerService extends IInputManager.Stub * Interface for the system to handle request from InputMonitors. */ private final class InputMonitorHost extends IInputMonitorHost.Stub { - private final IBinder mToken; + private IBinder mToken; InputMonitorHost(IBinder token) { mToken = token; @@ -3238,12 +3238,23 @@ public class InputManagerService extends IInputManager.Stub @Override public void pilferPointers() { + if (mToken == null) { + throw new IllegalStateException( + "Illegal call to pilferPointers after InputMonitorHost is disposed."); + } nativePilferPointers(mPtr, mToken); } @Override public void dispose() { - nativeRemoveInputChannel(mPtr, mToken); + // We do not remove the input monitor here by calling nativeRemoveInputChannel because + // it causes a race in InputDispatcher between the removal of the InputChannel through + // that call and the InputChannel#dispose call (which causes an FD hangup) from the + // client (b/189135695). + // + // NOTE: This means the client is responsible for properly closing the InputMonitor by + // disposing the InputChannel and all its duplicates. + mToken = null; } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java index 9d80b9c8b93e..2328dfc8b781 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java @@ -116,8 +116,10 @@ public abstract class InputMethodManagerInternal { * * @param windowToken the window token that is now in control, or {@code null} if no client * window is in control of the IME. + * @param imeParentChanged {@code true} when the window manager thoughts the IME surface parent + * will end up to change later, or {@code false} otherwise. */ - public abstract void reportImeControl(@Nullable IBinder windowToken); + public abstract void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged); /** * Destroys the IME surface. @@ -176,7 +178,8 @@ public abstract class InputMethodManagerInternal { } @Override - public void reportImeControl(@Nullable IBinder windowToken) { + public void reportImeControl(@Nullable IBinder windowToken, + boolean imeParentChanged) { } @Override diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index fd0f1c38938f..dc955337fdbc 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -4937,13 +4937,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken); } - private void reportImeControl(@Nullable IBinder windowToken) { + private void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) { synchronized (mMethodMap) { if (mCurFocusedWindow != windowToken) { // mCurPerceptible was set by the focused window, but it is no longer in control, // so we reset mCurPerceptible. mCurPerceptible = true; } + if (imeParentChanged) { + // Hide the IME method menu earlier when the IME surface parent will change in + // case seeing the dialog dismiss flickering during the next focused window + // starting the input connection. + mMenuController.hideInputMethodMenu(); + } } } @@ -5001,8 +5007,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void reportImeControl(@Nullable IBinder windowToken) { - mService.reportImeControl(windowToken); + public void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) { + mService.reportImeControl(windowToken, imeParentChanged); } @Override diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index ce195e6ddd64..aa4fa7c6f470 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -225,7 +225,8 @@ public final class MultiClientInputMethodManagerService { } @Override - public void reportImeControl(@Nullable IBinder windowToken) { + public void reportImeControl(@Nullable IBinder windowToken, + boolean imeParentChanged) { } @Override diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index bebe6ed8dc53..91f14de040fe 100644 --- a/services/core/java/com/android/server/lights/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -293,7 +293,7 @@ public class LightsService extends SystemService { + ": brightness=" + brightness); return; } - int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt(brightness, null); + int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt(brightness); int color = brightnessInt & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); diff --git a/services/core/java/com/android/server/media/MediaServerUtils.java b/services/core/java/com/android/server/media/MediaServerUtils.java index a4f11b2470f1..5fa2b1ceaae9 100644 --- a/services/core/java/com/android/server/media/MediaServerUtils.java +++ b/services/core/java/com/android/server/media/MediaServerUtils.java @@ -18,9 +18,6 @@ package com.android.server.media; import android.content.Context; import android.content.pm.PackageManager; -import android.media.AudioAttributes; -import android.media.AudioManager; -import android.media.AudioPlaybackConfiguration; import android.os.Binder; import java.io.PrintWriter; @@ -32,7 +29,7 @@ class MediaServerUtils { /** * Verify that caller holds {@link android.Manifest.permission#DUMP}. */ - static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) { + public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) { if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println("Permission Denial: can't dump " + tag + " from from pid=" @@ -43,18 +40,4 @@ class MediaServerUtils { return true; } } - - /** - * Whether the given stream is currently active or not. - */ - static boolean isStreamActive(AudioManager audioManager, int stream) { - for (AudioPlaybackConfiguration configuration - : audioManager.getActivePlaybackConfigurations()) { - AudioAttributes attributes = configuration.getAudioAttributes(); - if (attributes != null && attributes.getVolumeControlStream() == stream) { - return configuration.isActive(); - } - } - return false; - } } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index abcf4fb939e1..1525cd4da669 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -24,6 +24,7 @@ import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.AudioManager; +import android.media.AudioSystem; import android.media.MediaMetadata; import android.media.Rating; import android.media.VolumeProvider; @@ -515,7 +516,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR public void run() { try { if (useSuggested) { - if (MediaServerUtils.isStreamActive(mAudioManager, stream)) { + if (AudioSystem.isStreamActive(stream, 0)) { mAudioManager.adjustSuggestedStreamVolumeForUid(stream, direction, flags, opPackageName, uid, pid, mContext.getApplicationInfo().targetSdkVersion); diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 491cd181b6f9..b477ea353c25 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -42,6 +42,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.media.AudioManager; import android.media.AudioPlaybackConfiguration; +import android.media.AudioSystem; import android.media.IRemoteSessionCallback; import android.media.MediaCommunicationManager; import android.media.Session2Token; @@ -2147,7 +2148,7 @@ public class MediaSessionService extends SystemService implements Monitor { boolean preferSuggestedStream = false; if (isValidLocalStreamType(suggestedStream) - && MediaServerUtils.isStreamActive(mAudioManager, suggestedStream)) { + && AudioSystem.isStreamActive(suggestedStream, 0)) { preferSuggestedStream = true; } if (session == null || preferSuggestedStream) { @@ -2156,8 +2157,7 @@ public class MediaSessionService extends SystemService implements Monitor { + ". flags=" + flags + ", preferSuggestedStream=" + preferSuggestedStream + ", session=" + session); } - if (musicOnly && !MediaServerUtils.isStreamActive(mAudioManager, - AudioManager.STREAM_MUSIC)) { + if (musicOnly && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) { if (DEBUG_KEY_EVENT) { Log.d(TAG, "Nothing is playing on the music stream. Skipping volume event," + " flags=" + flags); diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index 50eed19389dc..c4c21df746b3 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -325,7 +325,8 @@ class MediaSessionStack { int size = records.size(); for (int i = 0; i < size; i++) { MediaSessionRecord record = records.get(i); - if (record.checkPlaybackActiveState(true)) { + // Do not send the volume key events to remote sessions. + if (record.checkPlaybackActiveState(true) && record.isPlaybackTypeLocal()) { mCachedVolumeDefault = record; return record; } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 4ee867b7d051..097b0711eff7 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -289,8 +289,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private String mActiveIface; /** Set of any ifaces associated with mobile networks since boot. */ - @GuardedBy("mStatsLock") - private String[] mMobileIfaces = new String[0]; + private volatile String[] mMobileIfaces = new String[0]; /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */ @GuardedBy("mStatsLock") @@ -935,7 +934,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public String[] getMobileIfaces() { - return mMobileIfaces; + // TODO (b/192758557): Remove debug log. + if (ArrayUtils.contains(mMobileIfaces, null)) { + throw new NullPointerException( + "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); + } + return mMobileIfaces.clone(); } @Override @@ -1084,7 +1088,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public long getIfaceStats(String iface, int type) { + public long getIfaceStats(@NonNull String iface, int type) { + Objects.requireNonNull(iface); long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable()); if (nativeIfaceStats == -1) { return nativeIfaceStats; @@ -1382,7 +1387,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); + mMobileIfaces = mobileIfaces.toArray(new String[0]); + // TODO (b/192758557): Remove debug log. + if (ArrayUtils.contains(mMobileIfaces, null)) { + throw new NullPointerException( + "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); + } } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java index 7627281d2188..3101ca7f9f6b 100644 --- a/services/core/java/com/android/server/pm/IncrementalStates.java +++ b/services/core/java/com/android/server/pm/IncrementalStates.java @@ -118,12 +118,19 @@ public final class IncrementalStates { * @param progress Value between [0, 1]. */ public void setProgress(float progress) { + final boolean oldLoadingState; final boolean newLoadingState; synchronized (mLock) { - updateProgressLocked(progress); + oldLoadingState = mLoadingState.isLoading(); + if (oldLoadingState) { + // Due to asynchronous progress reporting, incomplete progress might be received + // after the app is migrated off incremental. Ignore such progress updates. + updateProgressLocked(progress); + } newLoadingState = mLoadingState.isLoading(); } - if (!newLoadingState) { + if (oldLoadingState && !newLoadingState) { + // Only report the state change when loading state changes from true to false onLoadingStateChanged(); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ee44c10edbf3..031910a81260 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -24838,11 +24838,11 @@ public class PackageManagerService extends IPackageManager.Stub pw.println("vers,1"); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_VERSION) - && packageName == null) { - // dump version information for all volumes with installed packages - dump(DumpState.DUMP_VERSION, fd, pw, dumpState); + // reader + if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { + if (!checkin) { + dump(DumpState.DUMP_VERSION, fd, pw, dumpState); + } } if (!checkin @@ -24873,8 +24873,7 @@ public class PackageManagerService extends IPackageManager.Stub ipw.decreaseIndent(); } - if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { final String requiredVerifierPackage = mRequiredVerifierPackage; if (!checkin) { if (dumpState.onTitlePrinted()) { @@ -24895,8 +24894,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (dumpState.isDumping(DumpState.DUMP_DOMAIN_VERIFIER) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_DOMAIN_VERIFIER) && packageName == null) { final DomainVerificationProxy proxy = mDomainVerificationManager.getProxy(); final ComponentName verifierComponent = proxy.getComponentName(); if (verifierComponent != null) { @@ -24923,13 +24921,11 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (dumpState.isDumping(DumpState.DUMP_LIBS) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { dump(DumpState.DUMP_LIBS, fd, pw, dumpState); } - if (dumpState.isDumping(DumpState.DUMP_FEATURES) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { if (dumpState.onTitlePrinted()) { pw.println(); } @@ -24939,7 +24935,12 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mAvailableFeatures) { for (FeatureInfo feat : mAvailableFeatures.values()) { - if (!checkin) { + if (checkin) { + pw.print("feat,"); + pw.print(feat.name); + pw.print(","); + pw.println(feat.version); + } else { pw.print(" "); pw.print(feat.name); if (feat.version > 0) { @@ -24947,73 +24948,55 @@ public class PackageManagerService extends IPackageManager.Stub pw.print(feat.version); } pw.println(); - } else { - pw.print("feat,"); - pw.print(feat.name); - pw.print(","); - pw.println(feat.version); } } } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { synchronized (mLock) { mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { synchronized (mLock) { mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { synchronized (mLock) { mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { synchronized (mLock) { mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_PREFERRED) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { dump(DumpState.DUMP_PREFERRED, fd, pw, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { dump(DumpState.DUMP_PREFERRED_XML, fd, pw, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) { dump(DumpState.DUMP_DOMAIN_PREFERRED, fd, pw, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { mSettings.dumpPermissions(pw, packageName, permissionNames, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { synchronized (mLock) { mComponentResolver.dumpContentProviders(pw, dumpState, packageName); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { synchronized (mLock) { mSettings.getKeySetManagerService().dumpLPr(pw, packageName, dumpState); } @@ -25028,15 +25011,11 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_QUERIES) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_QUERIES)) { dump(DumpState.DUMP_QUERIES, fd, pw, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_SHARED_USERS) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { // This cannot be moved to ComputerEngine since the set of packages in the // SharedUserSetting do not have a copy. synchronized (mLock) { @@ -25044,9 +25023,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_CHANGES) - && packageName == null) { + if (dumpState.isDumping(DumpState.DUMP_CHANGES)) { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Package Changes:"); synchronized (mLock) { @@ -25073,9 +25050,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_FROZEN) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { // XXX should handle packageName != null by dumping only install data that // the given package is involved with. if (dumpState.onTitlePrinted()) pw.println(); @@ -25096,9 +25071,7 @@ public class PackageManagerService extends IPackageManager.Stub ipw.decreaseIndent(); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_VOLUMES) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) { if (dumpState.onTitlePrinted()) pw.println(); final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); @@ -25117,61 +25090,50 @@ public class PackageManagerService extends IPackageManager.Stub ipw.decreaseIndent(); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS) + if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS) && packageName == null) { synchronized (mLock) { mComponentResolver.dumpServicePermissions(pw, dumpState); } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_DEXOPT) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { if (dumpState.onTitlePrinted()) pw.println(); dump(DumpState.DUMP_DEXOPT, fd, pw, dumpState); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { if (dumpState.onTitlePrinted()) pw.println(); dump(DumpState.DUMP_COMPILER_STATS, fd, pw, dumpState); } - if (dumpState.isDumping(DumpState.DUMP_MESSAGES) - && packageName == null) { - if (!checkin) { - if (dumpState.onTitlePrinted()) pw.println(); - synchronized (mLock) { - mSettings.dumpReadMessagesLPr(pw, dumpState); - } - pw.println(); - pw.println("Package warning messages:"); - dumpCriticalInfo(pw, null); - } else { - dumpCriticalInfo(pw, "msg,"); + if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { + if (dumpState.onTitlePrinted()) pw.println(); + synchronized (mLock) { + mSettings.dumpReadMessagesLPr(pw, dumpState); } + pw.println(); + pw.println("Package warning messages:"); + dumpCriticalInfo(pw, null); + } + + if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { + dumpCriticalInfo(pw, "msg,"); } // PackageInstaller should be called outside of mPackages lock - if (!checkin - && dumpState.isDumping(DumpState.DUMP_INSTALLS) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { // XXX should handle packageName != null by dumping only install data that // the given package is involved with. if (dumpState.onTitlePrinted()) pw.println(); mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_APEX) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) { mApexManager.dump(pw, packageName); } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_PER_UID_READ_TIMEOUTS) + if (!checkin && dumpState.isDumping(DumpState.DUMP_PER_UID_READ_TIMEOUTS) && packageName == null) { pw.println(); pw.println("Per UID read timeouts:"); @@ -25190,9 +25152,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (!checkin - && dumpState.isDumping(DumpState.DUMP_SNAPSHOT_STATISTICS) - && packageName == null) { + if (!checkin && dumpState.isDumping(DumpState.DUMP_SNAPSHOT_STATISTICS)) { pw.println("Snapshot statistics"); if (!mSnapshotEnabled) { pw.println(" Snapshots disabled"); diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 2a5a7210635b..08a67d7f4bb5 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3347,13 +3347,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public void registerAttributionSource(@NonNull AttributionSource source) { - mAttributionSourceRegistry.registerAttributionSource(source); + public void registerAttributionSource(@NonNull AttributionSourceState source) { + mAttributionSourceRegistry + .registerAttributionSource(new AttributionSource(source)); } @Override - public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) { - return mAttributionSourceRegistry.isRegisteredAttributionSource(source); + public boolean isRegisteredAttributionSource(@NonNull AttributionSourceState source) { + return mAttributionSourceRegistry + .isRegisteredAttributionSource(new AttributionSource(source)); } @Override diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index fb4d96e305fc..e40882268e67 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3844,9 +3844,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { } mCameraGestureTriggered = false; final MutableBoolean outLaunched = new MutableBoolean(false); - mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched); + final boolean intercept = + mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched); if (!outLaunched.value) { - return false; + // If GestureLauncherService intercepted the power key, but didn't launch camera app, + // we should still return the intercept result. This prevents the single key gesture + // detector from processing the power key later on. + return intercept; } mCameraGestureTriggered = true; if (mRequestedOrSleepingDefaultDisplay) { diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index 9c3721b15f32..382398a210bb 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -596,7 +596,12 @@ public class Vcn extends Handler { /** Retrieves the network score for a VCN Network */ // Package visibility for use in VcnGatewayConnection and VcnNetworkProvider static NetworkScore getNetworkScore() { - return new NetworkScore.Builder().setLegacyInt(VCN_LEGACY_SCORE_INT).build(); + // TODO(b/193687515): Stop setting TRANSPORT_PRIMARY, define a TRANSPORT_VCN, and set in + // NetworkOffer/NetworkAgent. + return new NetworkScore.Builder() + .setLegacyInt(VCN_LEGACY_SCORE_INT) + .setTransportPrimary(true) + .build(); } /** Callback used for passing status signals from a VcnGatewayConnection to its managing Vcn. */ diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 3144c87e8314..1b799dfbdaab 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -61,6 +61,7 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN; @@ -728,13 +729,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // When switching the app task, we keep the IME window visibility for better // transitioning experiences. - // However, in case IME created a child window without dismissing during the task - // switching to keep the window focus because IME window has higher window hierarchy, - // we don't give it focus if the next IME layering target doesn't request IME visible. + // However, in case IME created a child window or the IME selection dialog without + // dismissing during the task switching to keep the window focus because IME window has + // higher window hierarchy, we don't give it focus if the next IME layering target + // doesn't request IME visible. if (w.mIsImWindow && w.isChildWindow() && (mImeLayeringTarget == null || !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) { return false; } + if (w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG && mImeLayeringTarget != null + && !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME) + && mImeLayeringTarget.isAnimating(PARENTS | TRANSITION, + ANIMATION_TYPE_APP_TRANSITION)) { + return false; + } final ActivityRecord activity = w.mActivityRecord; @@ -3977,7 +3985,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // Update Ime parent when IME insets leash created or the new IME layering target might // updated from setImeLayeringTarget, which is the best time that default IME visibility // has been settled down after IME control target changed. - if (prevImeControlTarget != mImeControlTarget || forceUpdateImeParent) { + final boolean imeParentChanged = + prevImeControlTarget != mImeControlTarget || forceUpdateImeParent; + if (imeParentChanged) { updateImeParent(); } @@ -3985,7 +3995,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final IBinder token = win != null ? win.mClient.asBinder() : null; // Note: not allowed to call into IMMS with the WM lock held, hence the post. mWmService.mH.post(() -> - InputMethodManagerInternal.get().reportImeControl(token) + InputMethodManagerInternal.get().reportImeControl(token, imeParentChanged) ); } @@ -5829,7 +5839,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return false; /* continue */ } } - + if (nextWindow.isSecureLocked()) { + return false; /* continue */ + } return true; /* stop, match found */ } }); diff --git a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java index 53b6b41db2ba..eab3f108d17a 100644 --- a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java +++ b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java @@ -66,10 +66,8 @@ public class FadeRotationAnimationController extends FadeAnimationController { } else { mNavBarToken = null; } - // Do not fade notification shade when running fixed rotation (not frozen) because it may - // need to animate with the launching app. - final WindowState notificationShade = mFrozenTimeoutRunnable == null - ? displayPolicy.getNotificationShade() : null; + // Collect the target windows to fade out. The display won't wait for them to unfreeze. + final WindowState notificationShade = displayPolicy.getNotificationShade(); displayContent.forAllWindows(w -> { if (w.mActivityRecord == null && w.mHasSurface && !w.mForceSeamlesslyRotate && !w.mIsWallpaper && !w.mIsImWindow && w != navigationBar diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index f2f192686ad5..11a0fba4b015 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -32,6 +32,10 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; +import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; +import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.StatusBarManager; @@ -211,7 +215,7 @@ class InsetsPolicy { InsetsState getInsetsForWindow(WindowState target) { final InsetsState originalState = mStateController.getInsetsForWindow(target); final InsetsState state = adjustVisibilityForTransientTypes(originalState); - return target.mIsImWindow ? adjustVisibilityForIme(state, state == originalState) : state; + return adjustVisibilityForIme(target, state, state == originalState); } /** @@ -241,16 +245,38 @@ class InsetsPolicy { return state; } - // Navigation bar insets is always visible to IME. - private static InsetsState adjustVisibilityForIme(InsetsState originalState, + private InsetsState adjustVisibilityForIme(WindowState w, InsetsState originalState, boolean copyState) { - final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR); - if (originalNavSource != null && !originalNavSource.isVisible()) { - final InsetsState state = copyState ? new InsetsState(originalState) : originalState; - final InsetsSource navSource = new InsetsSource(originalNavSource); - navSource.setVisible(true); - state.addSource(navSource); - return state; + if (w.mIsImWindow) { + // Navigation bar insets is always visible to IME. + final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR); + if (originalNavSource != null && !originalNavSource.isVisible()) { + final InsetsState state = copyState ? new InsetsState(originalState) + : originalState; + final InsetsSource navSource = new InsetsSource(originalNavSource); + navSource.setVisible(true); + state.addSource(navSource); + return state; + } + } else if (w.mActivityRecord != null && !w.mActivityRecord.mLastImeShown) { + // During switching tasks with gestural navigation, if the IME is attached to + // one app window on that time, even the next app window is behind the IME window, + // conceptually the window should not receive the IME insets if the next window is + // not eligible IME requester and ready to show IME on top of it. + final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp(); + final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME); + + if (originalImeSource != null && shouldImeAttachedToApp + && (w.isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS) + || !w.getRequestedVisibility(ITYPE_IME))) { + final InsetsState state = copyState ? new InsetsState(originalState) + : originalState; + + final InsetsSource imeSource = new InsetsSource(originalImeSource); + imeSource.setVisible(false); + state.addSource(imeSource); + return state; + } } return originalState; } diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java index b2471fac8b45..56bcb834dbfd 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java @@ -885,6 +885,7 @@ public class JobSchedulerServiceTest { // * E jobs test that expedited jobs don't skip the line when the app has no regular jobs // * F jobs test correct expedited/regular ordering doesn't push jobs too high in list // * G jobs test correct ordering for regular jobs + // * H job tests correct behavior when enqueue times are the same JobStatus rA1 = createJobStatus("testPendingJobSorting", createJobInfo(1), 1); JobStatus rB2 = createJobStatus("testPendingJobSorting", createJobInfo(2), 2); JobStatus eC3 = createJobStatus("testPendingJobSorting", @@ -896,6 +897,7 @@ public class JobSchedulerServiceTest { createJobInfo(6).setExpedited(true), 2); JobStatus eA7 = createJobStatus("testPendingJobSorting", createJobInfo(7).setExpedited(true), 1); + JobStatus rH8 = createJobStatus("testPendingJobSorting", createJobInfo(8), 14); JobStatus rF8 = createJobStatus("testPendingJobSorting", createJobInfo(8), 6); JobStatus eF9 = createJobStatus("testPendingJobSorting", createJobInfo(9).setExpedited(true), 6); @@ -915,6 +917,7 @@ public class JobSchedulerServiceTest { eB6.enqueueTime = 6; eA7.enqueueTime = 7; rF8.enqueueTime = 8; + rH8.enqueueTime = 8; eF9.enqueueTime = 9; rC10.enqueueTime = 10; eC11.enqueueTime = 11; @@ -931,6 +934,7 @@ public class JobSchedulerServiceTest { mService.mPendingJobs.add(rD4); mService.mPendingJobs.add(eA7); mService.mPendingJobs.add(rG12); + mService.mPendingJobs.add(rH8); mService.mPendingJobs.add(rF8); mService.mPendingJobs.add(eB6); mService.mPendingJobs.add(eE14); @@ -943,7 +947,7 @@ public class JobSchedulerServiceTest { mService.mPendingJobs.sort(mService.mPendingJobComparator); final JobStatus[] expectedOrder = new JobStatus[]{ - eA7, rA1, eB6, rB2, eC3, rD4, eE5, eF9, rF8, eC11, rC10, rG12, rG13, eE14}; + eA7, rA1, eB6, rB2, eC3, rD4, eE5, eF9, rH8, rF8, eC11, rC10, rG12, rG13, eE14}; for (int i = 0; i < expectedOrder.length; ++i) { assertEquals("List wasn't correctly sorted @ index " + i, expectedOrder[i].getJobId(), mService.mPendingJobs.get(i).getJobId()); @@ -995,7 +999,7 @@ public class JobSchedulerServiceTest { for (int i = 0; i < 2500; ++i) { JobStatus job = createJobStatus("testPendingJobSorting_Random", createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(250)); - job.enqueueTime = Math.abs(random.nextInt(1_000_000)); + job.enqueueTime = random.nextInt(1_000_000); mService.mPendingJobs.add(job); mService.mPendingJobComparator.refreshLocked(); @@ -1023,18 +1027,48 @@ public class JobSchedulerServiceTest { @Test public void testPendingJobSortingTransitivity() { - Random random = new Random(1); // Always use the same series of pseudo random values. + // Always use the same series of pseudo random values. + for (int seed : new int[]{1337, 7357, 606, 6357, 41106010, 3, 2, 1}) { + Random random = new Random(seed); + + mService.mPendingJobs.clear(); + + for (int i = 0; i < 300; ++i) { + JobStatus job = createJobStatus("testPendingJobSortingTransitivity", + createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(50)); + job.enqueueTime = random.nextInt(1_000_000); + job.overrideState = random.nextInt(4); + mService.mPendingJobs.add(job); + } - mService.mPendingJobs.clear(); + verifyPendingJobComparatorTransitivity(); + } + } - for (int i = 0; i < 250; ++i) { - JobStatus job = createJobStatus("testPendingJobSortingTransitivity", - createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(50)); - job.enqueueTime = Math.abs(random.nextInt(1_000_000)); - job.overrideState = random.nextInt(4); - mService.mPendingJobs.add(job); + @Test + public void testPendingJobSortingTransitivity_Concentrated() { + // Always use the same series of pseudo random values. + for (int seed : new int[]{1337, 6000, 637739, 6357, 1, 7, 13}) { + Random random = new Random(seed); + + mService.mPendingJobs.clear(); + + for (int i = 0; i < 300; ++i) { + JobStatus job = createJobStatus("testPendingJobSortingTransitivity_Concentrated", + createJobInfo(i).setExpedited(random.nextFloat() < .03), + random.nextInt(20)); + job.enqueueTime = random.nextInt(250); + job.overrideState = random.nextFloat() < .01 + ? JobStatus.OVERRIDE_SORTING : JobStatus.OVERRIDE_NONE; + mService.mPendingJobs.add(job); + Log.d(TAG, sortedJobToString(job)); + } + + verifyPendingJobComparatorTransitivity(); } + } + private void verifyPendingJobComparatorTransitivity() { mService.mPendingJobComparator.refreshLocked(); for (int i = 0; i < mService.mPendingJobs.size(); ++i) { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java index 7bf0bb873fc3..57ee7aa522c2 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java @@ -145,7 +145,6 @@ public class TouchExplorerTest { } mContext = InstrumentationRegistry.getContext(); mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); - AccessibilityManagerService ams = new AccessibilityManagerService(mContext); mCaptor = new EventCaptor(); mHandler = new TestHandler(); mTouchExplorer = new TouchExplorer(mContext, mMockAms, null, mHandler); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java index 1fe41234849f..8592166aae15 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java @@ -360,7 +360,8 @@ public class BiometricSchedulerTest { false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */, TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */, 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class), - false /* isKeyguard */, true /* shouldVibrate */); + false /* isKeyguard */, true /* shouldVibrate */, + false /* isKeyguardBypassEnabled */); } @Override @@ -388,7 +389,8 @@ public class BiometricSchedulerTest { false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */, TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */, 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class), - false /* isKeyguard */, true /* shouldVibrate */); + false /* isKeyguard */, true /* shouldVibrate */, + false /* isKeyguardBypassEnabled */); } @Override diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java index a169ebd0320f..7f5f3c2df077 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java @@ -17,6 +17,7 @@ package com.android.server.biometrics.sensors; import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE; +import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FP_OTHER; import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS; import static junit.framework.Assert.assertEquals; @@ -69,6 +70,7 @@ public class CoexCoordinatorTest { mCoexCoordinator = CoexCoordinator.getInstance(); mCoexCoordinator.setAdvancedLogicEnabled(true); + mCoexCoordinator.setFaceHapticDisabledWhenNonBypass(true); } @Test @@ -150,12 +152,76 @@ public class CoexCoordinatorTest { mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient, mCallback); - verify(mCallback).sendHapticFeedback(); + // Haptics tested in #testKeyguard_bypass_haptics. Let's leave this commented out (instead + // of removed) to keep this context. + // verify(mCallback).sendHapticFeedback(); verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */); verify(mCallback).handleLifecycleAfterAuth(); } @Test + public void testKeyguard_faceAuthSuccess_nonBypass_udfpsRunning_noHaptics() { + testKeyguard_bypass_haptics(false /* bypassEnabled */, + true /* faceAccepted */, + false /* shouldReceiveHaptics */); + } + + @Test + public void testKeyguard_faceAuthReject_nonBypass_udfpsRunning_noHaptics() { + testKeyguard_bypass_haptics(false /* bypassEnabled */, + false /* faceAccepted */, + false /* shouldReceiveHaptics */); + } + + @Test + public void testKeyguard_faceAuthSuccess_bypass_udfpsRunning_haptics() { + testKeyguard_bypass_haptics(true /* bypassEnabled */, + true /* faceAccepted */, + true /* shouldReceiveHaptics */); + } + + @Test + public void testKeyguard_faceAuthReject_bypass_udfpsRunning_haptics() { + testKeyguard_bypass_haptics(true /* bypassEnabled */, + false /* faceAccepted */, + true /* shouldReceiveHaptics */); + } + + private void testKeyguard_bypass_haptics(boolean bypassEnabled, boolean faceAccepted, + boolean shouldReceiveHaptics) { + mCoexCoordinator.reset(); + + AuthenticationClient<?> faceClient = mock(AuthenticationClient.class); + when(faceClient.isKeyguard()).thenReturn(true); + when(faceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled); + + AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class, + withSettings().extraInterfaces(Udfps.class)); + when(udfpsClient.isKeyguard()).thenReturn(true); + when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false); + + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient); + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient); + + if (faceAccepted) { + mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient, + mCallback); + } else { + mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient, + LockoutTracker.LOCKOUT_NONE, mCallback); + } + + if (shouldReceiveHaptics) { + verify(mCallback).sendHapticFeedback(); + } else { + verify(mCallback, never()).sendHapticFeedback(); + } + + verify(mCallback).sendAuthenticationResult(eq(faceAccepted) /* addAuthTokenIfStrong */); + verify(mCallback).handleLifecycleAfterAuth(); + } + + @Test public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedWithinBounds() { testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */, 0 /* udfpsRejectedAfterMs */); @@ -293,12 +359,13 @@ public class CoexCoordinatorTest { } @Test - public void testKeyguard_udfpsRejected_thenFaceRejected() { + public void testKeyguard_udfpsRejected_thenFaceRejected_noKeyguardBypass() { mCoexCoordinator.reset(); AuthenticationClient<?> faceClient = mock(AuthenticationClient.class); when(faceClient.isKeyguard()).thenReturn(true); when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED); + when(faceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class, withSettings().extraInterfaces(Udfps.class)); @@ -311,8 +378,9 @@ public class CoexCoordinatorTest { mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, udfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback); - // Client becomes paused, but finger does not necessarily lift, since we suppress the haptic - when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED_PAUSED); + // Auth was attempted + when(udfpsClient.getState()) + .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED); verify(mCallback, never()).sendHapticFeedback(); verify(mCallback).handleLifecycleAfterAuth(); @@ -327,6 +395,49 @@ public class CoexCoordinatorTest { } @Test + public void testKeyguard_capacitiveAccepted_whenFaceScanning() { + mCoexCoordinator.reset(); + + AuthenticationClient<?> faceClient = mock(AuthenticationClient.class); + when(faceClient.isKeyguard()).thenReturn(true); + when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED); + + AuthenticationClient<?> fpClient = mock(AuthenticationClient.class); + when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED); + when(fpClient.isKeyguard()).thenReturn(true); + + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient); + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient); + + mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, fpClient, mCallback); + verify(mCallback).sendHapticFeedback(); + verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */); + verify(mCallback).handleLifecycleAfterAuth(); + } + + @Test + public void testKeyguard_capacitiveRejected_whenFaceScanning() { + mCoexCoordinator.reset(); + + AuthenticationClient<?> faceClient = mock(AuthenticationClient.class); + when(faceClient.isKeyguard()).thenReturn(true); + when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED); + + AuthenticationClient<?> fpClient = mock(AuthenticationClient.class); + when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED); + when(fpClient.isKeyguard()).thenReturn(true); + + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient); + mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient); + + mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, fpClient, + LockoutTracker.LOCKOUT_NONE, mCallback); + verify(mCallback).sendHapticFeedback(); + verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */); + verify(mCallback).handleLifecycleAfterAuth(); + } + + @Test public void testNonKeyguard_rejectAndNotLockedOut() { mCoexCoordinator.reset(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index d498d4663d78..12fc2f4ea1f4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -42,6 +42,7 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -49,6 +50,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; @@ -1746,6 +1748,31 @@ public class DisplayContentTests extends WindowTestsBase { } @Test + public void testFindScrollCaptureTargetWindow_secure() { + DisplayContent display = createNewDisplay(); + Task rootTask = createTask(display); + Task task = createTaskInRootTask(rootTask, 0 /* userId */); + WindowState secureWindow = createWindow(null, TYPE_APPLICATION, "Secure Window"); + secureWindow.mAttrs.flags |= FLAG_SECURE; + + WindowState result = display.findScrollCaptureTargetWindow(null, + ActivityTaskManager.INVALID_TASK_ID); + assertNull(result); + } + + @Test + public void testFindScrollCaptureTargetWindow_secureTaskId() { + DisplayContent display = createNewDisplay(); + Task rootTask = createTask(display); + Task task = createTaskInRootTask(rootTask, 0 /* userId */); + WindowState secureWindow = createWindow(null, TYPE_APPLICATION, "Secure Window"); + secureWindow.mAttrs.flags |= FLAG_SECURE; + + WindowState result = display.findScrollCaptureTargetWindow(null, task.mTaskId); + assertNull(result); + } + + @Test public void testFindScrollCaptureTargetWindow_taskId() { DisplayContent display = createNewDisplay(); Task rootTask = createTask(display); @@ -2175,6 +2202,34 @@ public class DisplayContentTests extends WindowTestsBase { assertNotEquals(imeChildWindow, mDisplayContent.findFocusedWindow()); } + @UseTestDisplay(addWindows = W_INPUT_METHOD) + @Test + public void testImeMenuDialogFocusWhenImeLayeringTargetChanges() { + final WindowState imeMenuDialog = + createWindow(mImeWindow, TYPE_INPUT_METHOD_DIALOG, "imeMenuDialog"); + makeWindowVisibleAndDrawn(imeMenuDialog, mImeWindow); + assertTrue(imeMenuDialog.canReceiveKeys()); + mDisplayContent.setInputMethodWindowLocked(mImeWindow); + + // Verify imeMenuDialog can be focused window if the next IME target requests IME visible. + final WindowState imeAppTarget = + createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget"); + mDisplayContent.setImeLayeringTarget(imeAppTarget); + spyOn(imeAppTarget); + doReturn(true).when(imeAppTarget).getRequestedVisibility(ITYPE_IME); + assertEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); + + // Verify imeMenuDialog doesn't be focused window if the next IME target does not + // request IME visible. + final WindowState nextImeAppTarget = + createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "nextImeAppTarget"); + spyOn(nextImeAppTarget); + doReturn(true).when(nextImeAppTarget).isAnimating(PARENTS | TRANSITION, + ANIMATION_TYPE_APP_TRANSITION); + mDisplayContent.setImeLayeringTarget(nextImeAppTarget); + assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); + } + private void removeRootTaskTests(Runnable runnable) { final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 92b670ed9699..3a50bb0f06bc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -53,6 +53,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; +import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; +import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW; import static com.google.common.truth.Truth.assertThat; @@ -891,6 +894,36 @@ public class WindowStateTests extends WindowTestsBase { assertTrue(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR)); } + @UseTestDisplay(addWindows = W_INPUT_METHOD) + @Test + public void testAdjustImeInsetsVisibilityWhenTaskSwitchIsAnimating() { + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2"); + final InsetsStateController controller = mDisplayContent.getInsetsStateController(); + controller.getImeSourceProvider().setWindow(mImeWindow, null, null); + + // Simulate app requests IME with updating all windows Insets State when IME is above app. + mDisplayContent.setImeLayeringTarget(app); + mDisplayContent.setImeInputTarget(app); + assertTrue(mDisplayContent.shouldImeAttachedToApp()); + controller.getImeSourceProvider().scheduleShowImePostLayout(app); + controller.getImeSourceProvider().getSource().setVisible(true); + controller.updateAboveInsetsState(mImeWindow, false); + + // Simulate task switching animation happens when switching app to app2. + spyOn(app); + spyOn(app2); + doReturn(true).when(app).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS); + doReturn(true).when(app2).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS); + app.mActivityRecord.mLastImeShown = true; + + // Verify the IME insets is visible on app, but not for app2 during task animating. + InsetsState stateApp = app.getInsetsState(); + InsetsState stateApp2 = app2.getInsetsState(); + assertTrue(stateApp.getSource(ITYPE_IME).isVisible()); + assertFalse(stateApp2.getSource(ITYPE_IME).isVisible()); + } + @UseTestDisplay(addWindows = { W_ACTIVITY }) @Test public void testUpdateImeControlTargetWhenLeavingMultiWindow() { diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java index b9e1fcd7ffd3..68b2e6168b5c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java @@ -29,7 +29,6 @@ import android.media.permission.Identity; import android.media.permission.PermissionUtil; import android.os.IBinder; import android.os.RemoteException; -import android.os.ServiceSpecificException; import android.text.TextUtils; import android.util.Slog; @@ -117,8 +116,8 @@ final class SoundTriggerSessionPermissionsDecorator implements /** * Throws a {@link SecurityException} if originator permanently doesn't have the given - * permission, or a {@link ServiceSpecificException} with a {@link - * #TEMPORARY_PERMISSION_DENIED} if caller originator doesn't have the given permission. + * permission. + * Soft (temporary) denials are considered OK for preflight purposes. * * @param context A {@link Context}, used for permission checks. * @param identity The identity to check. @@ -130,15 +129,12 @@ final class SoundTriggerSessionPermissionsDecorator implements permission); switch (status) { case PermissionChecker.PERMISSION_GRANTED: + case PermissionChecker.PERMISSION_SOFT_DENIED: return; case PermissionChecker.PERMISSION_HARD_DENIED: throw new SecurityException( TextUtils.formatSimple("Failed to obtain permission %s for identity %s", permission, toString(identity))); - case PermissionChecker.PERMISSION_SOFT_DENIED: - throw new ServiceSpecificException(TEMPORARY_PERMISSION_DENIED, - TextUtils.formatSimple("Failed to obtain permission %s for identity %s", - permission, toString(identity))); default: throw new RuntimeException("Unexpected permission check result."); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 71541ad729d5..9ea2b7b12ad0 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -1896,17 +1896,19 @@ public class VoiceInteractionManagerService extends SystemService { String serviceComponentName = serviceInfo.getComponentName() .flattenToShortString(); - - String serviceRecognizerName = new ComponentName(pkg, - voiceInteractionServiceInfo.getRecognitionService()) - .flattenToShortString(); + if (voiceInteractionServiceInfo.getRecognitionService() == null) { + Slog.e(TAG, "The RecognitionService must be set to avoid boot " + + "loop on earlier platform version. Also make sure that this " + + "is a valid RecognitionService when running on Android 11 " + + "or earlier."); + serviceComponentName = ""; + } Settings.Secure.putStringForUser(getContext().getContentResolver(), Settings.Secure.ASSISTANT, serviceComponentName, userId); Settings.Secure.putStringForUser(getContext().getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE, serviceComponentName, userId); - return; } @@ -1947,6 +1949,29 @@ public class VoiceInteractionManagerService extends SystemService { } } + private void resetServicesIfNoRecognitionService(ComponentName serviceComponent, + int userHandle) { + for (ResolveInfo resolveInfo : queryInteractorServices(userHandle, + serviceComponent.getPackageName())) { + VoiceInteractionServiceInfo serviceInfo = + new VoiceInteractionServiceInfo( + mContext.getPackageManager(), + resolveInfo.serviceInfo); + if (!serviceInfo.getSupportsAssist()) { + continue; + } + if (serviceInfo.getRecognitionService() == null) { + Slog.e(TAG, "The RecognitionService must be set to " + + "avoid boot loop on earlier platform version. " + + "Also make sure that this is a valid " + + "RecognitionService when running on Android 11 " + + "or earlier."); + setCurInteractor(null, userHandle); + resetCurAssistant(userHandle); + } + } + } + PackageMonitor mPackageMonitor = new PackageMonitor() { @Override public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { @@ -2090,6 +2115,7 @@ public class VoiceInteractionManagerService extends SystemService { change = isPackageAppearing(curInteractor.getPackageName()); if (change != PACKAGE_UNCHANGED) { + resetServicesIfNoRecognitionService(curInteractor, userHandle); // If current interactor is now appearing, for any reason, then // restart our connection with it. if (mImpl != null && curInteractor.getPackageName().equals( @@ -2112,6 +2138,13 @@ public class VoiceInteractionManagerService extends SystemService { initForUser(userHandle); return; } + change = isPackageAppearing(curAssistant.getPackageName()); + if (change != PACKAGE_UNCHANGED) { + // It is possible to update Assistant without a voice interactor to one + // with a voice-interactor. We should make sure the recognition service + // is set to avoid boot loop. + resetServicesIfNoRecognitionService(curAssistant, userHandle); + } } // There is no interactor, so just deal with a simple recognizer. diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java index 6b820459be98..b5d97abdd3eb 100644 --- a/telephony/java/android/telephony/AccessNetworkUtils.java +++ b/telephony/java/android/telephony/AccessNetworkUtils.java @@ -567,6 +567,10 @@ public class AccessNetworkUtils { */ public static int getFrequencyFromNrArfcn(int nrArfcn) { + if (nrArfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { + return PhysicalChannelConfig.FREQUENCY_UNKNOWN; + } + int globalKhz = 0; int rangeOffset = 0; int arfcnOffset = 0; @@ -632,6 +636,10 @@ public class AccessNetworkUtils { */ public static int getFrequencyFromUarfcn(int band, int uarfcn, boolean isUplink) { + if (uarfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { + return PhysicalChannelConfig.FREQUENCY_UNKNOWN; + } + int offsetKhz = 0; for (UtranBandArfcnFrequency uarfcnFrequency : AccessNetworkConstants. UtranBandArfcnFrequency.values()) { @@ -702,6 +710,10 @@ public class AccessNetworkUtils { */ public static int getFrequencyFromArfcn(int band, int arfcn, boolean isUplink) { + if (arfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { + return PhysicalChannelConfig.FREQUENCY_UNKNOWN; + } + int uplinkFrequencyFirst = 0; int arfcnOffset = 0; int downlinkOffset = 0; diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index 72150ddf8597..6ada32e1a86d 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -178,7 +178,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23); mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3); mCsiCqiReport = csiCqiReport.stream() - .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 1, 3))) + .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))) .collect(Collectors.toList()); mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44); mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20); diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index 8df41fb6b288..d250088c2f10 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -338,7 +338,8 @@ public final class PhysicalChannelConfig implements Parcelable { private void setUplinkFrequency() { switch (mNetworkType){ case TelephonyManager.NETWORK_TYPE_NR: - mUplinkFrequency = mDownlinkFrequency; + mUplinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn( + mUplinkChannelNumber); break; case TelephonyManager.NETWORK_TYPE_LTE: mUplinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn( diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java index 72db55b3f4c5..e9026e22b6b2 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java @@ -87,8 +87,8 @@ public class VcnNetworkProviderTest { eq(mVcnNetworkProvider), argThat( score -> - score.getLegacyInt() - == Vcn.getNetworkScore().getLegacyInt()), + score.getLegacyInt() == Vcn.getNetworkScore().getLegacyInt() + && score.isTransportPrimary()), any(), any(), cbCaptor.capture()); |