Merge "Fix transition after restarting inactive media" into sc-dev
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a4ac61b..cb60b01 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2724,12 +2724,12 @@
public final class InputDevice implements android.os.Parcelable {
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void disable();
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void enable();
- field public static final int ACCESSIBILITY_DEVICE_ID = -2; // 0xfffffffe
}
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {
method public static String actionToString(int);
method public final void setDisplayId(int);
+ field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
field public static final int LAST_KEYCODE = 288; // 0x120
}
@@ -2747,6 +2747,7 @@
method public void setActionButton(int);
method public void setButtonState(int);
method public void setDisplayId(int);
+ field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
}
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 8a26578..b7d9d9b 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -640,4 +640,10 @@
* Returns the capability of the given uid
*/
public abstract @ProcessCapability int getUidCapability(int uid);
+
+ /**
+ * @return The PID list of the isolated process with packages matching the given uid.
+ */
+ @Nullable
+ public abstract List<Integer> getIsolatedProcesses(int uid);
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 034ad8e..00ba55c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -36,7 +36,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UserIdInt;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.backup.BackupAgent;
@@ -62,7 +61,6 @@
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Context.CreatePackageOptions;
import android.content.IContentProvider;
import android.content.IIntentReceiver;
import android.content.Intent;
@@ -73,7 +71,6 @@
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionInfo;
@@ -1172,6 +1169,7 @@
}
public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
+ mResourcesManager.updatePendingAppInfoUpdates(ai);
mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
sendMessage(H.APPLICATION_INFO_CHANGED, ai);
}
@@ -2376,22 +2374,16 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
- @CreatePackageOptions int flags) {
+ int flags) {
return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
}
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
- @CreatePackageOptions int flags, @UserIdInt int userId) {
- return getPackageInfo(packageName, compatInfo, flags, userId, 0 /* packageFlags */);
- }
-
- public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
- @CreatePackageOptions int flags, @UserIdInt int userId,
- @ApplicationInfoFlags int packageFlags) {
+ int flags, int userId) {
final boolean differentUser = (UserHandle.myUserId() != userId);
ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
packageName,
- packageFlags | PackageManager.GET_SHARED_LIBRARY_FILES
+ PackageManager.GET_SHARED_LIBRARY_FILES
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
(userId < 0) ? UserHandle.myUserId() : userId);
synchronized (mResourcesManager) {
@@ -2434,7 +2426,7 @@
@UnsupportedAppUsage(trackingBug = 171933273)
public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
- @CreatePackageOptions int flags) {
+ int flags) {
boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
boolean securityViolation = includeCode && ai.uid != 0
&& ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 16b6ea5..5e99c79 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -26,7 +26,6 @@
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -48,7 +47,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.content.res.CompatResources;
@@ -62,6 +60,7 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.content.AttributionSource;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -2494,13 +2493,6 @@
@Override
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws NameNotFoundException {
- return createPackageContextAsUser(packageName, flags, user, 0 /* packageFlags */);
- }
-
- @Override
- public Context createPackageContextAsUser(
- @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user,
- @ApplicationInfoFlags int packageFlags) throws PackageManager.NameNotFoundException {
if (packageName.equals("system") || packageName.equals("android")) {
// The system resources are loaded in every application, so we can safely copy
// the context without reloading Resources.
@@ -2511,7 +2503,7 @@
}
LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
- flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier(), packageFlags);
+ flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams,
mAttributionSource.getAttributionTag(),
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 506dfe0..6454d20 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6344,11 +6344,10 @@
ApplicationInfo applicationInfo = n.extras.getParcelable(
EXTRA_BUILDER_APPLICATION_INFO);
Context builderContext;
- if (applicationInfo != null && applicationInfo.packageName != null) {
+ if (applicationInfo != null) {
try {
- builderContext = context.createPackageContextAsUser(applicationInfo.packageName,
- Context.CONTEXT_RESTRICTED,
- UserHandle.getUserHandleForUid(applicationInfo.uid));
+ builderContext = context.createApplicationContext(applicationInfo,
+ Context.CONTEXT_RESTRICTED);
} catch (NameNotFoundException e) {
Log.e(TAG, "ApplicationInfo " + applicationInfo + " not found");
builderContext = context; // try with our context
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index e469b1f..dfd1e2b 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -98,6 +98,12 @@
private int mResDisplayId = DEFAULT_DISPLAY;
/**
+ * ApplicationInfo changes that need to be applied to Resources when the next configuration
+ * change occurs.
+ */
+ private ArrayList<ApplicationInfo> mPendingAppInfoUpdates;
+
+ /**
* A mapping of ResourceImpls and their configurations. These are heavy weight objects
* which should be reused as much as possible.
*/
@@ -988,7 +994,7 @@
* @param classLoader The classloader to use for the Resources object.
* If null, {@link ClassLoader#getSystemClassLoader()} is used.
* @return A Resources object that gets updated when
- * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
+ * {@link #applyConfigurationToResources(Configuration, CompatibilityInfo)}
* is called.
*/
@Nullable
@@ -1115,8 +1121,8 @@
/**
* Updates an Activity's Resources object with overrideConfig. The Resources object
* that was previously returned by {@link #getResources(IBinder, String, String[], String[],
- * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and
- * will have the updated configuration.
+ * String[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still
+ * valid and will have the updated configuration.
*
* @param activityToken The Activity token.
* @param overrideConfig The configuration override to update.
@@ -1267,6 +1273,22 @@
return newKey;
}
+ public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) {
+ synchronized (mLock) {
+ if (mPendingAppInfoUpdates == null) {
+ mPendingAppInfoUpdates = new ArrayList<>();
+ }
+ // Clear previous app info changes for the package to prevent multiple ResourcesImpl
+ // recreations when only the last recreation will be used.
+ for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
+ if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) {
+ mPendingAppInfoUpdates.remove(i);
+ }
+ }
+ mPendingAppInfoUpdates.add(appInfo);
+ }
+ }
+
public final boolean applyConfigurationToResources(@NonNull Configuration config,
@Nullable CompatibilityInfo compat) {
return applyConfigurationToResources(config, compat, null /* adjustments */);
@@ -1280,7 +1302,18 @@
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
"ResourcesManager#applyConfigurationToResources");
- if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
+ final boolean assetsUpdated = mPendingAppInfoUpdates != null
+ && config.assetsSeq > mResConfiguration.assetsSeq;
+ if (assetsUpdated) {
+ for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
+ final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i);
+ applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir});
+ }
+ mPendingAppInfoUpdates = null;
+ }
+
+ if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config)
+ && compat == null) {
if (DEBUG || DEBUG_CONFIGURATION) {
Slog.v(TAG, "Skipping new config: curSeq="
+ mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1320,7 +1353,7 @@
}
}
- return changes != 0;
+ return assetsUpdated || changes != 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 3b11a19..ba3fc1e 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -37,7 +37,6 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Parcelable;
-import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
@@ -719,10 +718,9 @@
protected Context getRemoteContext() {
try {
// Return if cloned successfully, otherwise default
- final ApplicationInfo info = mInfo.providerInfo.applicationInfo;
- Context newContext = mContext.createPackageContextAsUser(info.packageName,
- Context.CONTEXT_RESTRICTED,
- UserHandle.getUserHandleForUid(info.uid));
+ Context newContext = mContext.createApplicationContext(
+ mInfo.providerInfo.applicationInfo,
+ Context.CONTEXT_RESTRICTED);
if (mColorResources != null) {
mColorResources.apply(newContext);
}
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 54b39bd..0bc459a 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -179,6 +179,10 @@
final ArrayList<Item> mItems;
+ // This is false by default unless the ClipData is obtained via
+ // {@link #copyForTransferWithActivityInfo}.
+ private boolean mParcelItemActivityInfos;
+
/**
* Description of a single item in a ClipData.
*
@@ -204,9 +208,11 @@
final Intent mIntent;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Uri mUri;
- // Additional activity info resolved by the system
- ActivityInfo mActivityInfo;
private TextLinks mTextLinks;
+ // Additional activity info resolved by the system. This is only parceled with the ClipData
+ // if the data is obtained from {@link #copyForTransferWithActivityInfo}
+ private ActivityInfo mActivityInfo;
+
/** @hide */
public Item(Item other) {
@@ -214,6 +220,8 @@
mHtmlText = other.mHtmlText;
mIntent = other.mIntent;
mUri = other.mUri;
+ mActivityInfo = other.mActivityInfo;
+ mTextLinks = other.mTextLinks;
}
/**
@@ -817,6 +825,24 @@
}
/**
+ * Returns a copy of the ClipData which will parcel the Item's activity infos.
+ * @hide
+ */
+ public ClipData copyForTransferWithActivityInfo() {
+ ClipData copy = new ClipData(this);
+ copy.mParcelItemActivityInfos = true;
+ return copy;
+ }
+
+ /**
+ * Returns whether this clip data will parcel the Item's activity infos.
+ * @hide
+ */
+ public boolean willParcelWithActivityInfo() {
+ return mParcelItemActivityInfos;
+ }
+
+ /**
* Create a new ClipData holding data of the type
* {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.
*
@@ -1208,7 +1234,7 @@
dest.writeString8(item.mHtmlText);
dest.writeTypedObject(item.mIntent, flags);
dest.writeTypedObject(item.mUri, flags);
- dest.writeTypedObject(item.mActivityInfo, flags);
+ dest.writeTypedObject(mParcelItemActivityInfos ? item.mActivityInfo : null, flags);
dest.writeTypedObject(item.mTextLinks, flags);
}
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9c60f43..c02dcfd 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -46,7 +46,6 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.res.AssetManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -6269,23 +6268,6 @@
}
/**
- * Similar to {@link #createPackageContextAsUser(String, int, UserHandle)}, but also allows
- * specifying the flags used to retrieve the {@link ApplicationInfo} of the package.
- *
- * @hide
- */
- @NonNull
- public Context createPackageContextAsUser(
- @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user,
- @ApplicationInfoFlags int packageFlags)
- throws PackageManager.NameNotFoundException {
- if (Build.IS_ENG) {
- throw new IllegalStateException("createPackageContextAsUser not overridden!");
- }
- return this;
- }
-
- /**
* Similar to {@link #createPackageContext(String, int)}, but for the own package with a
* different {@link UserHandle}. For example, {@link #getContentResolver()}
* will open any {@link Uri} as the given user.
@@ -6304,18 +6286,10 @@
/**
* Creates a context given an {@link android.content.pm.ApplicationInfo}.
*
- * @deprecated use {@link #createPackageContextAsUser(String, int, UserHandle, int)}
- * If an application caches an ApplicationInfo and uses it to call this method,
- * the app will not get the most recent version of Runtime Resource Overlays for
- * that application. To make things worse, the LoadedApk stored in
- * {@code ActivityThread#mResourcePackages} is updated using the old ApplicationInfo
- * causing further uses of the cached LoadedApk to return outdated information.
- *
* @hide
*/
@SuppressWarnings("HiddenAbstractMethod")
@UnsupportedAppUsage
- @Deprecated
public abstract Context createApplicationContext(ApplicationInfo application,
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index cf0dc8c..6324d0e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1009,14 +1009,6 @@
/** @hide */
@Override
- public Context createPackageContextAsUser(String packageName, int flags, UserHandle user,
- int packageFlags)
- throws PackageManager.NameNotFoundException {
- return mBase.createPackageContextAsUser(packageName, flags, user, packageFlags);
- }
-
- /** @hide */
- @Override
public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
return mBase.createContextAsUser(user, flags);
}
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index e665d0f..4721f3e 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -209,7 +209,8 @@
FINGERPRINT_ACQUIRED_VENDOR,
FINGERPRINT_ACQUIRED_START,
FINGERPRINT_ACQUIRED_UNKNOWN,
- FINGERPRINT_ACQUIRED_IMMOBILE})
+ FINGERPRINT_ACQUIRED_IMMOBILE,
+ FINGERPRINT_ACQUIRED_TOO_BRIGHT})
@Retention(RetentionPolicy.SOURCE)
@interface FingerprintAcquired {}
@@ -287,6 +288,13 @@
int FINGERPRINT_ACQUIRED_IMMOBILE = 9;
/**
+ * For sensors that require illumination, such as optical under-display fingerprint sensors,
+ * the image was too bright to be used for matching.
+ * @hide
+ */
+ int FINGERPRINT_ACQUIRED_TOO_BRIGHT = 10;
+
+ /**
* @hide
*/
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 68dd6234..c104eeb 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1420,6 +1420,9 @@
case FINGERPRINT_ACQUIRED_IMMOBILE:
return context.getString(
com.android.internal.R.string.fingerprint_acquired_immobile);
+ case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+ return context.getString(
+ com.android.internal.R.string.fingerprint_acquired_too_bright);
case FINGERPRINT_ACQUIRED_VENDOR: {
String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.fingerprint_acquired_vendor);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 863d71f..8e4a68e 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -434,8 +434,11 @@
public Context getPackageContext(Context context) {
if (mContext == null) {
try {
- mContext = context.createPackageContextAsUser(pkg, Context.CONTEXT_RESTRICTED, user,
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ ApplicationInfo ai = context.getPackageManager()
+ .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ getUserId());
+ mContext = context.createApplicationContext(ai,
+ Context.CONTEXT_RESTRICTED);
} catch (PackageManager.NameNotFoundException e) {
mContext = null;
}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
index f122561..f69c89d 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
@@ -178,6 +178,14 @@
Drawable getLogo();
/**
+ * Returns the tile icon associated with the {@link QuickAccessWalletService}.
+ *
+ * @hide
+ */
+ @Nullable
+ Drawable getTileIcon();
+
+ /**
* Returns the service label specified by {@code android:label} in the service manifest entry.
*
* @hide
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
index 2e4af3f..2d0faad 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -307,6 +307,12 @@
return mServiceInfo == null ? null : mServiceInfo.getWalletLogo(mContext);
}
+ @Nullable
+ @Override
+ public Drawable getTileIcon() {
+ return mServiceInfo == null ? null : mServiceInfo.getTileIcon();
+ }
+
@Override
@Nullable
public CharSequence getServiceLabel() {
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
index ef6150d..db20a51 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
@@ -195,6 +195,13 @@
*/
public static final String SERVICE_META_DATA = "android.quickaccesswallet";
+ /**
+ * Name of the QuickAccessWallet tile service meta-data.
+ *
+ * @hide
+ */
+ public static final String TILE_SERVICE_META_DATA = "android.quickaccesswallet.tile";
+
private final Handler mHandler = new Handler(Looper.getMainLooper());
/**
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index c87407e..0d290ee 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -56,12 +56,15 @@
private final ServiceInfo mServiceInfo;
private final ServiceMetadata mServiceMetadata;
+ private final TileServiceMetadata mTileServiceMetadata;
private QuickAccessWalletServiceInfo(
@NonNull ServiceInfo serviceInfo,
- @NonNull ServiceMetadata metadata) {
+ @NonNull ServiceMetadata metadata,
+ @NonNull TileServiceMetadata tileServiceMetadata) {
mServiceInfo = serviceInfo;
mServiceMetadata = metadata;
+ mTileServiceMetadata = tileServiceMetadata;
}
@Nullable
@@ -84,7 +87,9 @@
}
ServiceMetadata metadata = parseServiceMetadata(context, serviceInfo);
- return new QuickAccessWalletServiceInfo(serviceInfo, metadata);
+ TileServiceMetadata tileServiceMetadata =
+ new TileServiceMetadata(parseTileServiceMetadata(context, serviceInfo));
+ return new QuickAccessWalletServiceInfo(serviceInfo, metadata, tileServiceMetadata);
}
private static ComponentName getDefaultPaymentApp(Context context) {
@@ -105,6 +110,31 @@
return resolveInfos.isEmpty() ? null : resolveInfos.get(0).serviceInfo;
}
+ private static class TileServiceMetadata {
+ @Nullable
+ private final Drawable mTileIcon;
+
+ private TileServiceMetadata(@Nullable Drawable tileIcon) {
+ mTileIcon = tileIcon;
+ }
+ }
+
+ @Nullable
+ private static Drawable parseTileServiceMetadata(Context context, ServiceInfo serviceInfo) {
+ PackageManager pm = context.getPackageManager();
+ int tileIconDrawableId =
+ serviceInfo.metaData.getInt(QuickAccessWalletService.TILE_SERVICE_META_DATA);
+ if (tileIconDrawableId != 0) {
+ try {
+ Resources resources = pm.getResourcesForApplication(serviceInfo.applicationInfo);
+ return resources.getDrawable(tileIconDrawableId, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Error parsing quickaccesswallet tile service meta-data", e);
+ }
+ }
+ return null;
+ }
+
private static class ServiceMetadata {
@Nullable
private final String mSettingsActivity;
@@ -216,6 +246,11 @@
return mServiceInfo.loadIcon(context.getPackageManager());
}
+ @Nullable
+ Drawable getTileIcon() {
+ return mTileServiceMetadata.mTileIcon;
+ }
+
@NonNull
CharSequence getShortcutShortLabel(Context context) {
if (!TextUtils.isEmpty(mServiceMetadata.mShortcutShortLabel)) {
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 782a992..4f1354d 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -444,13 +444,6 @@
private static final int VIBRATOR_ID_ALL = -1;
- /**
- * The device id of input events generated inside accessibility service.
- * @hide
- */
- @TestApi
- public static final int ACCESSIBILITY_DEVICE_ID = -2;
-
public static final @android.annotation.NonNull Parcelable.Creator<InputDevice> CREATOR =
new Parcelable.Creator<InputDevice>() {
public InputDevice createFromParcel(Parcel in) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 37f0a64..cda9b23 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
import static android.view.Display.INVALID_DISPLAY;
import android.annotation.NonNull;
@@ -1222,6 +1223,14 @@
public static final int FLAG_FALLBACK = 0x400;
/**
+ * This flag indicates that this event was modified by or generated from an accessibility
+ * service. Value = 0x800
+ * @hide
+ */
+ @TestApi
+ public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
+
+ /**
* Signifies that the key is being predispatched.
* @hide
*/
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 0483d0b..69ff64f 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
import static android.view.Display.DEFAULT_DISPLAY;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -494,6 +495,14 @@
public static final int FLAG_NO_FOCUS_CHANGE = 0x40;
/**
+ * This flag indicates that this event was modified by or generated from an accessibility
+ * service. Value = 0x800
+ * @hide
+ */
+ @TestApi
+ public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
+
+ /**
* Private flag that indicates when the system has detected that this motion event
* may be inconsistent with respect to the sequence of previously delivered motion events,
* such as when a pointer move event is sent but the pointer is not down.
diff --git a/core/java/android/view/VerifiedInputEvent.java b/core/java/android/view/VerifiedInputEvent.java
index e2db501..cc6fbe7 100644
--- a/core/java/android/view/VerifiedInputEvent.java
+++ b/core/java/android/view/VerifiedInputEvent.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
@@ -157,4 +158,28 @@
throw new IllegalArgumentException("Unexpected input event type in parcel.");
}
};
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ @SuppressWarnings("unchecked")
+ VerifiedInputEvent that = (VerifiedInputEvent) o;
+ return mType == that.mType
+ && getDeviceId() == that.getDeviceId()
+ && getEventTimeNanos() == that.getEventTimeNanos()
+ && getSource() == that.getSource()
+ && getDisplayId() == that.getDisplayId();
+ }
+
+ @Override
+ public int hashCode() {
+ int _hash = 1;
+ _hash = 31 * _hash + mType;
+ _hash = 31 * _hash + getDeviceId();
+ _hash = 31 * _hash + Long.hashCode(getEventTimeNanos());
+ _hash = 31 * _hash + getSource();
+ _hash = 31 * _hash + getDisplayId();
+ return _hash;
+ }
}
diff --git a/core/java/android/view/VerifiedKeyEvent.java b/core/java/android/view/VerifiedKeyEvent.java
index 77a7d09..fc357cc 100644
--- a/core/java/android/view/VerifiedKeyEvent.java
+++ b/core/java/android/view/VerifiedKeyEvent.java
@@ -17,6 +17,7 @@
package android.view;
import static android.view.KeyEvent.FLAG_CANCELED;
+import static android.view.KeyEvent.FLAG_IS_ACCESSIBILITY_EVENT;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -72,6 +73,7 @@
*
* @see KeyEvent#getFlags()
* @see KeyEvent#FLAG_CANCELED
+ * @see KeyEvent#FLAG_IS_ACCESSIBILITY_EVENT
*
* @hide
*/
@@ -125,6 +127,7 @@
// InputDispatcher only verifies a subset of the KeyEvent flags.
// These values must be kept in sync with Input.cpp
case FLAG_CANCELED:
+ case FLAG_IS_ACCESSIBILITY_EVENT:
return (mFlags & flag) != 0;
}
return null;
diff --git a/core/java/android/view/VerifiedMotionEvent.java b/core/java/android/view/VerifiedMotionEvent.java
index 7d83459..948575c 100644
--- a/core/java/android/view/VerifiedMotionEvent.java
+++ b/core/java/android/view/VerifiedMotionEvent.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT;
import static android.view.MotionEvent.FLAG_WINDOW_IS_OBSCURED;
import static android.view.MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
@@ -83,6 +84,9 @@
* Returns the flags for this motion event.
*
* @see MotionEvent#getFlags()
+ * @see MotionEvent#FLAG_IS_ACCESSIBILITY_EVENT
+ * @see MotionEvent#FLAG_WINDOW_IS_OBSCURED
+ * @see MotionEvent#FLAG_WINDOW_IS_PARTIALLY_OBSCURED
* @hide
*/
private int mFlags;
@@ -117,6 +121,7 @@
switch(flag) {
// InputDispatcher only verifies a subset of the MotionEvent flags.
// These values must be kept in sync with Input.cpp
+ case FLAG_IS_ACCESSIBILITY_EVENT:
case FLAG_WINDOW_IS_OBSCURED:
case FLAG_WINDOW_IS_PARTIALLY_OBSCURED:
return (mFlags & flag) != 0;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5a248af..23faac6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1442,8 +1442,10 @@
if (mHardwareRendererObserver != null) {
mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
}
- addPrepareSurfaceControlForWebviewCallback();
- addASurfaceTransactionCallback();
+ if (HardwareRenderer.isWebViewOverlaysEnabled()) {
+ addPrepareSurfaceControlForWebviewCallback();
+ addASurfaceTransactionCallback();
+ }
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
}
}
@@ -7777,8 +7779,10 @@
}
}
if (mAttachInfo.mThreadedRenderer != null) {
- addPrepareSurfaceControlForWebviewCallback();
- addASurfaceTransactionCallback();
+ if (HardwareRenderer.isWebViewOverlaysEnabled()) {
+ addPrepareSurfaceControlForWebviewCallback();
+ addASurfaceTransactionCallback();
+ }
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
}
} else {
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 81c934d..bbef3e6 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -17,7 +17,6 @@
package android.view;
import static android.os.IInputConstants.POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
-import static android.os.IInputConstants.POLICY_FLAG_INPUTFILTER_TRUSTED;
import android.annotation.IntDef;
import android.os.PowerManager;
@@ -35,7 +34,6 @@
int FLAG_WAKE = 0x00000001;
int FLAG_VIRTUAL = 0x00000002;
- int FLAG_INPUTFILTER_TRUSTED = POLICY_FLAG_INPUTFILTER_TRUSTED;
int FLAG_INJECTED_FROM_ACCESSIBILITY = POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
int FLAG_INJECTED = 0x01000000;
int FLAG_TRUSTED = 0x02000000;
diff --git a/core/java/android/view/translation/ITranslationManager.aidl b/core/java/android/view/translation/ITranslationManager.aidl
index 5fbf228..cce0193 100644
--- a/core/java/android/view/translation/ITranslationManager.aidl
+++ b/core/java/android/view/translation/ITranslationManager.aidl
@@ -16,6 +16,7 @@
package android.view.translation;
+import android.content.ComponentName;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.ResultReceiver;
@@ -47,4 +48,6 @@
void registerUiTranslationStateCallback(in IRemoteCallback callback, int userId);
void unregisterUiTranslationStateCallback(in IRemoteCallback callback, int userId);
void getServiceSettingsActivity(in IResultReceiver result, int userId);
+ void onTranslationFinished(boolean activityDestroyed, IBinder token,
+ in ComponentName componentName, int userId);
}
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 592993c..2c17545 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -24,6 +24,7 @@
import android.annotation.NonNull;
import android.annotation.WorkerThread;
import android.app.Activity;
+import android.app.assist.ActivityId;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
@@ -161,6 +162,7 @@
view.setHasTranslationTransientState(false);
}
});
+ notifyTranslationFinished(/* activityDestroyed= */ false);
synchronized (mLock) {
mViews.clear();
}
@@ -175,12 +177,28 @@
*/
public void onActivityDestroyed() {
synchronized (mLock) {
+ if (DEBUG) {
+ Log.i(TAG,
+ "onActivityDestroyed(): mCurrentState is " + stateToString(mCurrentState));
+ }
+ if (mCurrentState != STATE_UI_TRANSLATION_FINISHED) {
+ notifyTranslationFinished(/* activityDestroyed= */ true);
+ }
mViews.clear();
destroyTranslators();
mWorkerThread.quitSafely();
}
}
+ private void notifyTranslationFinished(boolean activityDestroyed) {
+ UiTranslationManager manager = mContext.getSystemService(UiTranslationManager.class);
+ if (manager != null) {
+ manager.onTranslationFinished(activityDestroyed,
+ new ActivityId(mActivity.getTaskId(), mActivity.getShareableActivityToken()),
+ mActivity.getComponentName());
+ }
+ }
+
private void setLastRequestAutofillIdsLocked(List<AutofillId> views) {
if (mLastRequestAutofillIds == null) {
mLastRequestAutofillIds = new ArraySet<>();
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index 3350c93..b9ed32c 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -22,6 +22,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.assist.ActivityId;
+import android.content.ComponentName;
import android.content.Context;
import android.icu.util.ULocale;
import android.os.Binder;
@@ -308,6 +309,26 @@
}
}
+ /**
+ * Notify apps the translation is finished because {@link #finishTranslation(ActivityId)} is
+ * called or Activity is destroyed.
+ *
+ * @param activityDestroyed if the ui translation is finished because of activity destroyed.
+ * @param activityId the identifier for the Activity which needs ui translation
+ * @param componentName the ui translated Activity componentName.
+ *
+ * @hide
+ */
+ public void onTranslationFinished(boolean activityDestroyed, ActivityId activityId,
+ ComponentName componentName) {
+ try {
+ mService.onTranslationFinished(activityDestroyed,
+ activityId.getToken(), componentName, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
@NonNull
@GuardedBy("mCallbacks")
private final Map<UiTranslationStateCallback, IRemoteCallback> mCallbacks = new ArrayMap<>();
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 8d27cde..cf6807e 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -33,7 +33,6 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
-import android.os.UserHandle;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
import android.util.Log;
@@ -468,12 +467,9 @@
sTimestamps.mCreateContextStart = SystemClock.uptimeMillis();
try {
// Construct an app context to load the Java code into the current app.
- Context webViewContext = initialApplication.createPackageContextAsUser(
- ai.packageName,
- Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY,
- UserHandle.getUserHandleForUid(ai.uid),
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+ Context webViewContext = initialApplication.createApplicationContext(
+ ai,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
sPackageInfo = newPackageInfo;
return webViewContext;
} finally {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8a044fd..e827f0a 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5831,9 +5831,8 @@
return context;
}
try {
- return context.createPackageContextAsUser(mApplication.packageName,
- Context.CONTEXT_RESTRICTED,
- UserHandle.getUserHandleForUid(mApplication.uid));
+ return context.createApplicationContext(mApplication,
+ Context.CONTEXT_RESTRICTED);
} catch (NameNotFoundException e) {
Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 7000ed7..a6bf3cf 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1186,7 +1186,7 @@
final DisplayResolveInfo dri = new DisplayResolveInfo(
originalIntent, ri, getString(R.string.screenshot_edit), "", resolveIntent, null);
- dri.setDisplayIcon(getDrawable(R.drawable.ic_menu_edit));
+ dri.setDisplayIcon(getDrawable(R.drawable.ic_screenshot_edit));
return dri;
}
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
index 18bbd93..518d51a 100644
--- a/core/res/res/drawable/chooser_action_button_bg.xml
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -23,8 +23,9 @@
android:insetRight="0dp"
android:insetBottom="8dp">
<shape android:shape="rectangle">
- <corners android:radius="16dp" />
- <solid android:color="@color/system_neutral2_100" />
+ <corners android:radius="8dp" />
+ <stroke android:width="1dp"
+ android:color="?android:attr/colorAccentPrimaryVariant"/>
</shape>
</inset>
</item>
diff --git a/core/res/res/drawable/ic_screenshot_edit.xml b/core/res/res/drawable/ic_screenshot_edit.xml
new file mode 100644
index 0000000..2d9148f
--- /dev/null
+++ b/core/res/res/drawable/ic_screenshot_edit.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 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:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l0,0L3,16.82V21h4.18L20.41,7.77C21.2,6.99 21.2,5.72 20.41,4.94zM6.41,19.06L5,19v-1.36l9.82,-9.82l1.41,1.41L6.41,19.06z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
index def429e..2b68ccc 100644
--- a/core/res/res/layout/chooser_action_button.xml
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -19,13 +19,13 @@
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:drawablePadding="8dp"
- android:textColor="@color/text_color_primary_device_default_light"
+ android:textColor="?android:attr/textColorPrimary"
android:textSize="12sp"
android:maxWidth="192dp"
android:singleLine="true"
android:clickable="true"
android:background="@drawable/chooser_action_button_bg"
- android:drawableTint="@color/text_color_primary_device_default_light"
+ android:drawableTint="?android:attr/textColorPrimary"
android:drawableTintMode="src_in"
style="?android:attr/borderlessButtonStyle"
/>
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 10683b1..90caacc 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -51,6 +51,7 @@
android:paddingBottom="@dimen/chooser_view_spacing"
android:paddingLeft="24dp"
android:paddingRight="24dp"
+ android:visibility="gone"
android:layout_below="@id/drag"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 39e3021..664c314 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -614,8 +614,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"لا يمكن استخدام مستشعر بصمات الإصبع. يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
@@ -631,12 +630,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"يمكنك فتح قفل هاتفك بمجرّد النظر إلى الشاشة."</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"إعداد المزيد من الطرق لفتح قفل الجهاز"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"انقر لإضافة بصمة إصبع."</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"فتح الجهاز ببصمة الإصبع"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"لا يمكن استخدام مستشعر بصمات الإصبع"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"تعذّر تسجيل بيانات دقيقة للوجه. حاول مرة أخرى."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"الصورة معتمة للغاية. يُرجى زيادة السطوع."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index ad3d746..a55785f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি। মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
@@ -613,20 +612,15 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"মুখাৱয়বৰ দ্বাৰা আনলক কৰাৰ সুবিধা"</string>
- <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
- <skip />
- <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
- <skip />
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"মুখাৱয়বৰ দ্বাৰা আনলক কৰাৰ সুবিধাটোৰ ব্যৱহাৰ কৰোঁতে সমস্যা হৈছে"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"আপোনাৰ মুখাৱয়বৰ মডেলটো মচিবলৈ টিপক, তাৰ পাছত পুনৰ আপোনাৰ মুখাৱয়ব যোগ দিয়ক"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"মুখাৱয়বৰে আনলক কৰাৰ সুবিধাটো ছেট আপ কৰক"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"আপোনাৰ ফ’নটোলৈ চাই সেইটো আনলক কৰক"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক কৰাৰ অধিক উপায় ছেট আপ কৰক"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"এটা ফিংগাৰপ্ৰিণ্ট যোগ দিবলৈ টিপক"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ফিংগাৰপ্ৰিণ্টৰ দ্বাৰা আনলক কৰা সুবিধা"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক।"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"সঠিক মুখমণ্ডলৰ ডেটা কেপচাৰ নহ’ল। আকৌ চেষ্টা কৰক।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"অতি উজ্জ্বল। ইয়াতকৈ কম পোহৰৰ উৎস ব্যৱহাৰ কৰক।"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"অতি আন্ধাৰ। উজ্জ্বল লাইট ব্যৱহাৰ কৰক।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 85f1b47..a9b8ccb 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmaq izi sensorundan istifadə etmək mümkün deyil. Təmir provayderini ziyarət edin"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Telefona baxaraq onu kiliddən çıxarın"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kiliddən çıxarmağın daha çox yolunu ayarlayın"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmaq izi əlavə etmək üçün toxunun"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Barmaq izi ilə kiliddən çıxarma"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Barmaq izi sensorundan istifadə etmək mümkün deyil"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Təmir provayderini ziyarət edin."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Dəqiq üz datası əldə edilmədi. Yenidən cəhd edin."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Çox işıqlıdır. Daha az işıqlı şəkli sınayın."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Çox qaranlıqdır. Parlaq işıqdan istifadə edin."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 003b5e5..9c5b71f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -608,8 +608,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не ўдалося скарыстаць сканер адбіткаў пальцаў. Звярніцеся ў сэрвісны цэнтр."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
@@ -625,12 +624,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Разблакіруйце свой тэлефон, паглядзеўшы на яго"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Наладзьце дадатковыя спосабы разблакіроўкі"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Націсніце, каб дадаць адбітак пальца"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Разблакіраванне адбіткам пальца"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не ўдалося скарыстаць сканер адбіткаў пальцаў"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Звярніцеся ў сэрвісны цэнтр."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Не атрымалася распазнаць твар. Паўтарыце спробу."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадта светла. Прыглушыце асвятленне."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Занадта цёмна. Павялічце асвятленне."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5af538d..ededf28 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Der Fingerabdrucksensor kann nicht verwendet werden. Suche einen Reparaturdienstleister auf."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Entsperre dein Smartphone, indem du es ansiehst"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Weitere Möglichkeiten zum Entsperren einrichten"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tippe, um einen Fingerabdruck hinzuzufügen"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Entsperrung per Fingerabdruck"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Der Fingerabdrucksensor kann nicht verwendet werden"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Suche einen Reparaturdienstleister auf."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Gesichtsdaten nicht gut erfasst. Erneut versuchen."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Zu hell. Schwächere Beleuchtung ausprobieren."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Zu dunkel. Probier eine hellere Beleuchtung aus."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index c3172a6..6e0cdaf 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -602,7 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
- <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jo konponketak egiten dituen hornitzaile batenera."</string>
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
@@ -620,7 +620,7 @@
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Sakatu hau hatz-marka bat gehitzeko"</string>
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Hatz-marka bidez desblokeatzea"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ezin da erabili hatz-marken sentsorea"</string>
- <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jo konponketak egiten dituen hornitzaile batenera."</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Ezin izan dira bildu argazkiaren datu zehatzak. Saiatu berriro."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Argi gehiegi dago. Joan toki ilunago batera."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Ilunegi dago. Erabili argi gehiago."</string>
@@ -2061,7 +2061,7 @@
<string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
<string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefonoa ezin da erabili ahotsa erabiltzeko"</string>
<string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
- <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartelik"</string>
+ <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIMik"</string>
<string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
<string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
<string name="popup_window_default_title" msgid="6907717596694826919">"Leiho gainerakorra"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 69daf30..57b99f0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le lecteur d\'empreinte digitale. Contactez un réparateur"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Impossible d\'utiliser le lecteur d\'empreinte digitale"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contactez un réparateur."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Capture du visage impossible. Réessayez."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez de baisser la lumière."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez une éclairage plus lumineux."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6dcb8ef5..7ebd2d9 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -613,10 +613,8 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ફેસ અનલૉક"</string>
- <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
- <skip />
- <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
- <skip />
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ફેસ અનલૉકની સુવિધામાં સમસ્યા"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"તમારા ચહેરાનું મૉડલ ડિલીટ કરવા માટે ટૅપ કરો, પછી તમારો ચહેરો ફરીથી ઉમેરો"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"ફેસ અનલૉક સુવિધાનું સેટઅપ કરો"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"તમારા ફોનની તરફ જોઈને તેને અનલૉક કરો"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"અનલૉક કરવાની બીજી રીતોનું સેટઅપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 9a205dd..6aa2570 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -176,9 +176,9 @@
<string name="contentServiceSync" msgid="2341041749565687871">"समन्वयन"</string>
<string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"सिंक नहीं किया जा सकता"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"बहुत ज़्यादा <xliff:g id="CONTENT_TYPE">%s</xliff:g> मिटाने की कोशिश की गई."</string>
- <string name="low_memory" product="tablet" msgid="5557552311566179924">"टैबलेट की मेमोरी भर गई है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
- <string name="low_memory" product="watch" msgid="3479447988234030194">"घड़ी की मेमोरी भर गई है. स्थान खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिवाइस की मेमोरी में जगह नहीं बची है. जगह बनाने के लिए कुछ फाइलें मिटाएं."</string>
+ <string name="low_memory" product="tablet" msgid="5557552311566179924">"टैबलेट का स्टोरेज भर गया है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+ <string name="low_memory" product="watch" msgid="3479447988234030194">"घड़ी का स्टोरेज भर गया है. स्थान खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिवाइस के स्टोरेज में जगह नहीं बची है. जगह बनाने के लिए कुछ फाइलें मिटाएं."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"फ़ोन मेमोरी भर गयी है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="one">प्रमाणपत्र अनुमतियों को इंस्टॉल किया गया</item>
@@ -408,9 +408,9 @@
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"यह ऐप्लिकेशन को सिस्टम के शुरू होने की प्रक्रिया पूरा होते ही अपने आप चालू होने की अनुमति देता है. इससे आपके Android TV डिवाइस को चालू होने में ज़्यादा समय लग सकता है और ऐप्लिकेशन के हमेशा चालू रहने की वजह से आपके टीवी की परफ़ॉर्मेंस पर असर पड़ सकता है."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"सिस्टम के चालू होते ही ऐप को अपने आप शुरू होने देती है. इससे फ़ोन को चालू होने में ज़्यादा समय लग सकता है और ऐप के लगातार चलते रहने से पूरा फ़ोन धीमा हो सकता है."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"स्टिकी प्रसारण भेजें"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टैबलेट की बहुत ज़्यादा मेमोरी का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टैबलेट की बहुत ज़्यादा स्टोरेज का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"यह ऐप्लिकेशन को स्टिकी ब्रॉडकास्ट भेजने की अनुमति देता है जो ब्रॉडकास्ट खत्म होने के बाद भी बने रहते हैं. इस सुविधा के ज़्यादा इस्तेमाल से आपके Android TV डिवाइस की मेमोरी कम हो सकती है जिससे टीवी की परफ़ॉर्मेंस पर असर पड़ सकता है और उसे इस्तेमाल करने में समस्याएं आ सकती हैं."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत ज़्यादा मेमोरी का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत ज़्यादा स्टोरेज का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"अपने संपर्क पढ़ें"</string>
<string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"यह ऐप्लिकेशन को आपके टैबलेट पर मौजूद संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके टैबलेट पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
<string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके Android TV डिवाइस पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता. रिपेयर की सेवा देने वाली कंपनी से संपर्क करें"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
@@ -613,18 +612,15 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फ़ेस अनलॉक"</string>
- <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फ़ेस अनलॉक के साथ कोई समस्या है"</string>
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फ़ेस अनलॉक से जुड़ी समस्या"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"अपने चेहरे का मॉडल मिटाने के लिए टैप करें. इसके बाद, अपना चेहरा फिर से रजिस्टर करें"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"फे़स अनलॉक की सुविधा सेट अप करें"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"अपने फ़ोन की तरफ़ देखकर उसे अनलॉक करें"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"फ़ोन को अनलॉक करने के दूसरे तरीके सेट अप करें"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फ़िंगरप्रिंट जोड़ने के लिए टैप करें"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"फ़िंगरप्रिंट अनलॉक"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फ़िंगरप्रिंट सेंसर को रिपेयर करने की सेवा देने वाली कंपनी से संपर्क करें."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"चेहरे से जुड़ा सटीक डेटा कैप्चर नहीं किया जा सका. फिर से कोशिश करें."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"बहुत रोशनी है. हल्की रोशनी आज़माएं."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"बहुत अंधेरा है. बेहतर रोशनी में आज़माएं."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5aacfa71..874d56d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -608,8 +608,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
@@ -625,12 +624,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"יש להביט בטלפון כדי לבטל את נעילתו"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"אפשר להגדיר דרכים נוספות לביטול נעילה"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"יש להקיש כדי להוסיף טביעת אצבע"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ביטול הנעילה בטביעת אצבע"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"לא ניתן להשתמש בחיישן טביעות האצבע"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"צריך ליצור קשר עם ספק תיקונים."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"בהירה מדי. צריך תאורה עדינה יותר."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"התמונה חשוכה מדי. צריך תאורה חזקה יותר."</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 8a68fb9..d6950dee 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება. ეწვიეთ შეკეთების სერვისის პროვაიდერს"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"განბლოკეთ თქვენი ტელეფონი შეხედვით"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"დააყენეთ განბლოკვის სხვა ხერხები"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"შეეხეთ თითის ანაბეჭდის დასამატებლად"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"თითის ანაბეჭდით განბლოკვა"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ეწვიეთ შეკეთების სერვისის პროვაიდერს."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"სახის ზუსტი მონაცემები არ აღიბეჭდა. ცადეთ ხელახლა."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"მეტისმეტად ნათელია. ცადეთ უფრო სუსტი განათება."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"მეტისმეტად ბნელია. ცადეთ უფრო ძლიერი განათება."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index df6a2aa..9a283e6 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Саусақ ізін оқу сканерін пайдалану мүмкін емес. Жөндеу қызметіне барыңыз."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Телефоныңызға қарап, оның құлпын ашыңыз."</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Құлыпты ашудың басқа тәсілдерін реттеу"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Саусақ ізін қосу үшін түртіңіз."</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Құлыпты саусақ ізімен ашу"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Саусақ ізін оқу сканерін пайдалану мүмкін емес"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Жөндеу қызметіне барыңыз."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Бет деректері дұрыс алынбады. Әрекетті қайталаңыз."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Тым ашық. Күңгірттеу жарық керек."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Тым қараңғы. Молырақ жарық керек."</string>
@@ -2103,7 +2099,7 @@
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Жарайды"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Өшіру"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
- <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде кеңейтілген хабарландырулар функциясы бейімделетін хабарландырулар функциясын алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарлар) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беру және \"Мазаламау\" режимін басқару) болады."</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде кеңейтілген хабарландырулар функциясы бейімделетін хабарландырулар функциясын алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарлар) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беру және Мазаламау режимін басқару) болады."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Батареяны үнемдеу режимі іске қосылды"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 17b550db..2172553 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -228,7 +228,7 @@
<string name="reboot_to_update_prepare" msgid="6978842143587422365">"ಅಪ್ಡೇಟೇ ಮಾಡಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
<string name="reboot_to_update_package" msgid="4644104795527534811">"ಅಪ್ಡೇಟ್ ಪ್ಯಾಕೇಜ್ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"ಮರುಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
- <string name="reboot_to_reset_title" msgid="2226229680017882787">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆ"</string>
+ <string name="reboot_to_reset_title" msgid="2226229680017882787">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್"</string>
<string name="reboot_to_reset_message" msgid="3347690497972074356">"ಮರುಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
<string name="shutdown_progress" msgid="5017145516412657345">"ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತಿದೆ…"</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ."</string>
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"ಫೋನ್ ಅನ್ನು ನೋಡುವ ಮೂಲಕ ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಹೆಚ್ಚಿನ ಮಾರ್ಗಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಸೇರಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ಲಾಕ್"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ಸರಿಯಾಗಿ ಮುಖ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಲಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ ಮಂದ ಪ್ರಕಾಶಮಾನವಿರುವ ಲೈಟ್ ಬಳಸಿ"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ತುಂಬಾ ಕಪ್ಪು ಛಾಯೆಯಿದೆ. ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ."</string>
@@ -741,9 +737,9 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಮಾಡಿ"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"ಪರದೆಯು ಯಾವಾಗ ಮತ್ತು ಹೇಗೆ ಲಾಕ್ ಆಗಬೇಕೆಂಬುದನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿ"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಟ್ಯಾಬ್ಲೆಟ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆ ಮಾಡುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ನಿಮ್ಮ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಫೋನ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಅನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಟ್ಯಾಬ್ಲೆಟ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
+ <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಮಾಡುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ನಿಮ್ಮ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಅನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಫೋನ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
<string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"ಬಳಕೆದಾರ ಡೇಟಾ ಅಳಿಸಿ"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"ಯಾವುದೇ ಸೂಚನೆ ಇಲ್ಲದೆ ಈ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ಈ Android TV ಸಾಧನದಲ್ಲಿನ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
@@ -921,9 +917,9 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್ ಇನ್ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. ಇನ್ನೂ <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Google ಸೈನ್ ಇನ್ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್ ಇನ್ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಇದೀಗ ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಫೋನ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
@@ -1679,9 +1675,9 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"ನಿಮ್ಮ ಪಿನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಇದೀಗ ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಫೋನ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಢೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
@@ -1928,7 +1924,7 @@
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ಈವೆಂಟ್"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ನಿದ್ರೆಯ ಸಮಯ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string>
- <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ಮರುಹೊಂದಿಸುವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
+ <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ. ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ತಯಾರಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD ವಿನಂತಿಯನ್ನು ಸಾಮಾನ್ಯ ಕರೆಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
<string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD ವಿನಂತಿಯನ್ನು SS ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 820a79c..fb79335 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Манжа изинин сенсорун колдонууга болбойт. Тейлөө кызматына кайрылыңыз"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Телефонуңузду карап туруп эле кулпусун ачып алыңыз"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Манжа изин кошуу үчүн басыңыз"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Кулпуланган түзмөктү манжа изи менен ачуу"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Манжа изинин сенсорун колдонууга болбойт"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Тейлөө кызматына кайрылыңыз."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string>
diff --git a/core/res/res/values-mcc310-mnc030-eu/strings.xml b/core/res/res/values-mcc310-mnc030-eu/strings.xml
index 936ec1e..45ce091 100644
--- a/core/res/res/values-mcc310-mnc030-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="1782569305985001089">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="8246632898824321280">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
index 7cffce7..76e30b0 100644
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="3527626511418944853">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="3948912590657398489">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
index a2f0130..fbf7044 100644
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="499832197298480670">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="2346111479504469688">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc380-eu/strings.xml b/core/res/res/values-mcc310-mnc380-eu/strings.xml
index 0f2ae51..c3fb1bc 100644
--- a/core/res/res/values-mcc310-mnc380-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-eu/strings.xml
@@ -20,6 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="6084322234976891423">"Ez da onartzen SIM txartela MM#3"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
index a41129a..b023bcc 100644
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="2604694337529846283">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="3099618295079374317">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc560-eu/strings.xml b/core/res/res/values-mcc310-mnc560-eu/strings.xml
index 5f1e1fff..a0a46f6 100644
--- a/core/res/res/values-mcc310-mnc560-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="4618730283812066268">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="8522039751358990401">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
index 355b551..5a34371 100644
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="7801541624846497489">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="7066936962628406316">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
index f5d7afb..d843c4f 100644
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-eu/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"Ez dago SIM txartelik MM#2"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"Ez dago SIMik MM#2"</string>
<string name="mmcc_illegal_ms" msgid="4073997279280371621">"Ez da onartzen SIM txartela MM#3"</string>
<string name="mmcc_illegal_me" msgid="4936539345546223576">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 929d032..69c803d 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन। फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
@@ -613,20 +612,15 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फेस अनलक"</string>
- <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
- <skip />
- <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
- <skip />
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फेस अनलक सुविधामा अनुहार दर्ता गर्ने क्रममा त्रुटि भयो"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"आफ्नो फेस मोडेल मेटाउन ट्याप गर्नुहोस् अनि आफ्नो अनुहार फेरि दर्ता गर्नुहोस्"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"फेस अनलक सेटअप गर्नुहोस्"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"फोनमा हेरेकै भरमा फोन अनलक गर्नुहोस्"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"अनलक गर्ने अन्य तरिकाहरू सेटअप गर्नुहोस्"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फिंगरप्रिन्ट हाल्न ट्याप गर्नुहोस्"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"फिंगरप्रिन्ट अनलक"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्।"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"अनुहारको सटीक डेटा खिच्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ज्यादै चम्किलो। अझ मधुरो प्रकाश प्रयोग गरी हेर्नु…"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ज्यादै अँध्यारो छ। अझ बढी प्रकाशमा गई हेर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7401212..867bb85 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1717,7 +1717,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string>
- <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met één hand"</string>
+ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met 1 hand"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra gedimd"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 7885f67..277e0a5 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନ୍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"ଫୋନକୁ ଦେଖି ଏହାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ଅନଲକ୍ କରିବା ପାଇଁ ଆହୁରି ଅଧିକ ଉପାୟ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ଏକ ଟିପଚିହ୍ନ ଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ୍"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ।"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ମୁହଁର ଡାଟା କ୍ୟାପଚର୍ ହେଲାନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ଅତ୍ୟଧିକ ଉଜ୍ଵଳ। କମ୍ ଉଜ୍ବଳକରଣରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ଅତ୍ୟଧିକ ଅନ୍ଧକାର। ଉଜ୍ବଳ ଲାଇଟ୍ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index f5f8a55..ea94b05 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -613,10 +613,8 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ਫ਼ੇਸ ਅਣਲਾਕ"</string>
- <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
- <skip />
- <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
- <skip />
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ਫ਼ੇਸ ਅਣਲਾਕ ਨਾਲ ਸਮੱਸਿਆ"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ਆਪਣੇ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਮਿਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ, ਫਿਰ ਆਪਣਾ ਚਿਹਰਾ ਦੁਬਾਰਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"ਆਪਣੇ ਫ਼ੋਨ ਵੱਲ ਦੇਖ ਕੇ ਇਸਨੂੰ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ਅਣਲਾਕ ਕਰਨ ਦੇ ਹੋਰ ਤਰੀਕਿਆਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8e0f2b4..8ff3837 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -2165,7 +2165,7 @@
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Wyłącz"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Więcej informacji"</string>
- <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"W Androidzie 12 ulepszone powiadomienia zastąpiły dotychczasowe powiadomienia adaptacyjne. Ta funkcja pokazuje sugerowane działania i odpowiedzi oraz porządkuje powiadomienia.\n\nUlepszone powiadomienia mogą czytać całą zawartość powiadomień, w tym dane osobowe takie jak nazwy kontaktów i treść wiadomości. Funkcja może też zamykać powiadomienia oraz reagować na nie, np. odbierać połączenia telefoniczne i sterować trybem Nie przeszkadzać."</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"W Androidzie 12 ulepszone powiadomienia zastąpiły dotychczasowe powiadomienia adaptacyjne. Ta funkcja pokazuje sugerowane działania i odpowiedzi oraz porządkuje powiadomienia.\n\nUlepszone powiadomienia mogą czytać całą zawartość powiadomień, w tym informacje osobiste takie jak nazwy kontaktów i treść wiadomości. Funkcja może też zamykać powiadomienia oraz reagować na nie, np. odbierać połączenia telefoniczne i sterować trybem Nie przeszkadzać."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Powiadomienie z informacją o trybie rutynowym"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5a37821..d4befd4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -605,8 +605,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nu se poate folosi senzorul de amprentă. Vizitați un furnizor de servicii de reparații."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
@@ -622,12 +621,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Deblocați-vă telefonul uitându-vă la acesta"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurați mai multe moduri de deblocare"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Atingeți ca să adăugați o amprentă"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Deblocare cu amprenta"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nu se poate folosi senzorul de amprentă"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizitați un furnizor de servicii de reparații."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Nu s-a putut fotografia fața cu precizie. Încercați din nou."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încercați o lumină mai slabă."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Prea întunecat. Încercați o lumină mai puternică."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 6820452..e73a3c6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -2165,7 +2165,7 @@
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ОК"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Отключить"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
- <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивные уведомления заменены улучшенными. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 доступны улучшенные уведомления. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея может разрядиться"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f44c8d8..20a8e15 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -26,7 +26,7 @@
<string name="gigabyteShort" msgid="7515809460261287991">"GB"</string>
<string name="terabyteShort" msgid="1822367128583886496">"TB"</string>
<string name="petabyteShort" msgid="5651571254228534832">"PB"</string>
- <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+ <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g>&#160;<xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="3381766946944136678">"<Bez mena>"</string>
<string name="emptyPhoneNumber" msgid="5812172618020360048">"(žiadne telefónne číslo)"</string>
<string name="unknownName" msgid="7078697621109055330">"Bez názvu"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 57c1297..1a4531f 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sensori i gjurmës së gishtit nuk mund të përdoret. Vizito një ofrues të shërbimit të riparimit"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
@@ -613,18 +612,15 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Shkyçja me fytyrë"</string>
- <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Lëshoje me \"Shkyçjen me fytyrë\""</string>
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem me \"Shkyçjen me fytyrë\""</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Trokit për të fshirë modelin tënd të fytyrës, pastaj shtoje përsëri fytyrën tënde"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguro \"Shkyçjen me fytyrë\""</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Shkyçe telefonin duke parë tek ai"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguri më shumë mënyra për të shkyçur"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Trokit për të shtuar një gjurmë gishti"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Shkyçja me gjurmën e gishtit"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Sensori i gjurmës së gishtit nuk mund të përdoret"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizito një ofrues të shërbimit të riparimit."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"S\'mund të regjistroheshin të dhëna të sakta të fytyrës. Provo përsëri."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Me shumë ndriçim. Provo një ndriçim më të butë."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Shumë i errët. Provo një ndriçim më të fortë."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 26fa15b..dd75160 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை. பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"மொபைலைப் பார்ப்பதன் மூலம் அதைத் திறக்கலாம்"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"திறக்க, மேலும் பல வழிகளை அமையுங்கள்"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"கைரேகையைச் சேர்க்கத் தட்டுங்கள்"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"கைரேகை அன்லாக்"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"முகம் தெளிவாகப் பதிவாகவில்லை. மீண்டும் முயலவும்."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"அதிக ஒளிர்வு. மிதமான ஒளியில் முயலவும்."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"இருட்டாக உள்ளது. பிரகாசமான ஒளியில் முயலவும்."</string>
@@ -1871,7 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"அகற்றும் முன் PINஐக் கேள்"</string>
- <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் திறத்தல் வடிவத்தைக் கேள்"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"உங்கள் நிர்வாகி நிறுவியுள்ளார்"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6c92268..017f4cf 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -787,7 +787,7 @@
<item msgid="7640927178025203330">"అనుకూలం"</item>
</string-array>
<string-array name="organizationTypes">
- <item msgid="6144047813304847762">"కార్యాలయం"</item>
+ <item msgid="6144047813304847762">"వర్క్"</item>
<item msgid="7402720230065674193">"ఇతరం"</item>
<item msgid="808230403067569648">"అనుకూలం"</item>
</string-array>
@@ -849,7 +849,7 @@
<string name="imProtocolIcq" msgid="2410325380427389521">"ICQ"</string>
<string name="imProtocolJabber" msgid="7919269388889582015">"Jabber"</string>
<string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
- <string name="orgTypeWork" msgid="8684458700669564172">"కార్యాలయం"</string>
+ <string name="orgTypeWork" msgid="8684458700669564172">"వర్క్"</string>
<string name="orgTypeOther" msgid="5450675258408005553">"ఇతరం"</string>
<string name="orgTypeCustom" msgid="1126322047677329218">"అనుకూలం"</string>
<string name="relationTypeCustom" msgid="282938315217441351">"అనుకూలం"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b35ddab..1ea7cbf 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้ โปรดติดต่อผู้ให้บริการซ่อม"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"ปลดล็อกโทรศัพท์โดยมองไปที่โทรศัพท์"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ตั้งค่าการปลดล็อกด้วยวิธีอื่น"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"แตะเพื่อเพิ่มลายนิ้วมือ"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ปลดล็อกด้วยลายนิ้วมือ"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"โปรดติดต่อผู้ให้บริการซ่อม"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"บันทึกข้อมูลใบหน้าที่ถูกต้องไม่ได้ ลองอีกครั้ง"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"สว่างเกินไป ลองหาตำแหน่งที่แสงน้อยกว่านี้"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"มืดเกินไป ลองหาตำแหน่งที่สว่างขึ้น"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index a00b051..85624f1 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے۔ ایک مرمت فراہم کنندہ کو ملاحظہ کریں"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"اپنے فون کی طرف دیکھ کر اسے غیر مقفل کریں"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"غیر مقفل کرنے کے مزید طریقے سیٹ اپ کریں"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"فنگر پرنٹ شامل کرنے کیلئے تھپتھپائیں"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"فنگر پرنٹ اَن لاک"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ایک مرمت فراہم کنندہ کو ملاحظہ کریں۔"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"چہرے کا درست ڈيٹا کیپچر نہیں ہو سکا۔ پھر آزمائيں۔"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"کافی روشنی ہے۔ ہلکی روشنی میں آزمائیں۔"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"کافی اندھیرا ہے۔ تیز روشنی میں آزمائیں۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 045c62d..51e2b88 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmoq izi skaneridan foydalanish imkonsiz. Xizmat koʻrsatish markaziga murojaat qiling"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Telefoningizni yuz tekshiruvi yordamida qulfdan chiqaring"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Qulfdan chiqarishning boshqa usullarini sozlang"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmoq izi kiritish uchun bosing"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Barmoq izi bilan ochish"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Barmoq izi skaneridan foydalanish imkonsiz"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Xizmat koʻrsatish markaziga murojaat qiling."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Yuz ravshan suratga olinmadi. Qaytadan urining."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Juda yorqin. Biroz soyaroq joy tanlang."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Juda qorongʻi. Atrofingizni yoriting."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index eb23130..77b48e7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -602,8 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
- <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
- <skip />
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"无法使用指纹传感器。请联系维修服务提供商"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
@@ -619,12 +618,9 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"脸部对准手机即可将其解锁"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"设置更多解锁方式"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"点按即可添加指纹"</string>
- <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
- <skip />
- <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
- <skip />
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指纹解锁"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"无法使用指纹传感器"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"请联系维修服务提供商。"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"无法捕获准确的人脸数据,请重试。"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度过高,请尝试使用较柔和的亮度。"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"亮度不足,请尝试将光线调亮。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c2bce46..06bb2d9 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -602,7 +602,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
- <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string>
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"無法使用指紋感應器。請諮詢維修服務供應商"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
@@ -619,8 +619,8 @@
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方法"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕按即可新增指紋"</string>
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指紋解鎖"</string>
- <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"指紋感應器無法使用"</string>
- <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請洽詢維修供應商。"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"無法使用指紋感應器"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請諮詢維修服務供應商。"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"無法擷取準確的臉容資料。請再試一次。"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"影像太亮。請嘗試在更暗的環境下使用。"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"影像太暗。請嘗試在更明亮的環境下使用。"</string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ea93520..de7a117 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -886,7 +886,7 @@
<dimen name="seekbar_thumb_exclusion_max_size">48dp</dimen>
<!-- chooser/resolver (sharesheet) spacing -->
- <dimen name="chooser_corner_radius">8dp</dimen>
+ <dimen name="chooser_corner_radius">16dp</dimen>
<dimen name="chooser_row_text_option_translate">25dp</dimen>
<dimen name="chooser_view_spacing">18dp</dimen>
<dimen name="chooser_edge_margin_thin">16dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b76a780..bfd39a3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2528,6 +2528,7 @@
<java-symbol type="string" name="fingerprint_acquired_imager_dirty" />
<java-symbol type="string" name="fingerprint_acquired_too_slow" />
<java-symbol type="string" name="fingerprint_acquired_too_fast" />
+ <java-symbol type="string" name="fingerprint_acquired_too_bright" />
<java-symbol type="array" name="fingerprint_acquired_vendor" />
<java-symbol type="string" name="fingerprint_error_canceled" />
<java-symbol type="string" name="fingerprint_error_user_canceled" />
@@ -4167,6 +4168,7 @@
<java-symbol type="drawable" name="ic_work_apps_off" />
<java-symbol type="drawable" name="ic_sharing_disabled" />
<java-symbol type="drawable" name="ic_no_apps" />
+ <java-symbol type="drawable" name="ic_screenshot_edit" />
<java-symbol type="dimen" name="resolver_empty_state_height" />
<java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" />
<java-symbol type="dimen" name="resolver_max_collapsed_height_with_tabs" />
diff --git a/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt b/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
index 2c4851f..29ad0aa 100644
--- a/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
+++ b/core/tests/coretests/src/android/view/VerifiedMotionEventTest.kt
@@ -18,6 +18,7 @@
import android.view.InputDevice.SOURCE_TOUCHSCREEN
import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT
import android.view.MotionEvent.FLAG_WINDOW_IS_OBSCURED
import android.view.MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED
import android.view.MotionEvent.FLAG_TAINTED
@@ -49,6 +50,7 @@
assertEquals(RAW_Y, event.rawY, 0f)
assertEquals(ACTION_MASKED, event.actionMasked)
assertEquals(DOWN_TIME_NANOS, event.downTimeNanos)
+ assertEquals(FLAGS, event.flags)
assertEquals(META_STATE, event.metaState)
assertEquals(BUTTON_STATE, event.buttonState)
}
@@ -128,8 +130,9 @@
assertNull(motionEvent.getFlag(0))
// Flag that was not set
assertEquals(false, motionEvent.getFlag(FLAG_WINDOW_IS_PARTIALLY_OBSCURED))
- // Flag that was set
+ // Flags that were set
assertEquals(true, motionEvent.getFlag(FLAG_WINDOW_IS_OBSCURED))
+ assertEquals(true, motionEvent.getFlag(FLAG_IS_ACCESSIBILITY_EVENT))
// Only 1 flag at a time is accepted
assertNull(motionEvent.getFlag(
FLAG_WINDOW_IS_PARTIALLY_OBSCURED or FLAG_WINDOW_IS_OBSCURED))
@@ -153,7 +156,7 @@
private const val RAW_Y = 200f
private const val ACTION_MASKED = ACTION_MOVE
private const val DOWN_TIME_NANOS: Long = 1000
- private const val FLAGS = FLAG_WINDOW_IS_OBSCURED
+ private const val FLAGS = FLAG_WINDOW_IS_OBSCURED or FLAG_IS_ACCESSIBILITY_EVENT
private const val META_STATE = 11
private const val BUTTON_STATE = 22
@@ -178,6 +181,7 @@
assertEquals(event1.rawY, event2.rawY, 0f)
assertEquals(event1.actionMasked, event2.actionMasked)
assertEquals(event1.downTimeNanos, event2.downTimeNanos)
+ assertEquals(event1.flags, event2.flags)
assertEquals(event1.metaState, event2.metaState)
assertEquals(event1.buttonState, event2.buttonState)
}
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 30d1e0f..fe04f0d 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -1304,6 +1304,11 @@
*/
public static native void preload();
+ /**
+ * @hide
+ */
+ public static native boolean isWebViewOverlaysEnabled();
+
/** @hide */
protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 69fc25a..06aaad7 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -45,10 +45,10 @@
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
<string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bovenste scherm 30%"</string>
<string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Onderste scherm op volledig scherm"</string>
- <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met één hand gebruiken"</string>
+ <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met 1 hand gebruiken"</string>
<string name="one_handed_tutorial_description" msgid="3486582858591353067">"Als je wilt afsluiten, swipe je omhoog vanaf de onderkant van het scherm of tik je ergens boven de app"</string>
- <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met één hand starten"</string>
- <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Bediening met één hand afsluiten"</string>
+ <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met 1 hand starten"</string>
+ <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Bediening met 1 hand afsluiten"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"Instellingen voor <xliff:g id="APP_NAME">%1$s</xliff:g>-bubbels"</string>
<string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Overloop"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Weer toevoegen aan stack"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index cb27ad9..f565724 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -159,6 +159,14 @@
}
}
+ private void dispatchImeControlTargetChanged(int displayId, boolean controlling) {
+ synchronized (mPositionProcessors) {
+ for (ImePositionProcessor pp : mPositionProcessors) {
+ pp.onImeControlTargetChanged(displayId, controlling);
+ }
+ }
+ }
+
private void dispatchVisibilityChanged(int displayId, boolean isShowing) {
synchronized (mPositionProcessors) {
for (ImePositionProcessor pp : mPositionProcessors) {
@@ -237,42 +245,52 @@
protected void insetsControlChanged(InsetsState insetsState,
InsetsSourceControl[] activeControls) {
insetsChanged(insetsState);
+ InsetsSourceControl imeSourceControl = null;
if (activeControls != null) {
for (InsetsSourceControl activeControl : activeControls) {
if (activeControl == null) {
continue;
}
if (activeControl.getType() == InsetsState.ITYPE_IME) {
- final Point lastSurfacePosition = mImeSourceControl != null
- ? mImeSourceControl.getSurfacePosition() : null;
- final boolean positionChanged =
- !activeControl.getSurfacePosition().equals(lastSurfacePosition);
- final boolean leashChanged =
- !haveSameLeash(mImeSourceControl, activeControl);
- final InsetsSourceControl lastImeControl = mImeSourceControl;
- mImeSourceControl = activeControl;
- if (mAnimation != null) {
- if (positionChanged) {
- startAnimation(mImeShowing, true /* forceRestart */);
- }
- } else {
- if (leashChanged) {
- applyVisibilityToLeash();
- }
- if (!mImeShowing) {
- removeImeSurface();
- }
- }
- if (lastImeControl != null) {
- lastImeControl.release(SurfaceControl::release);
- }
+ imeSourceControl = activeControl;
}
}
}
+
+ final boolean hadImeSourceControl = mImeSourceControl != null;
+ final boolean hasImeSourceControl = imeSourceControl != null;
+ if (hadImeSourceControl != hasImeSourceControl) {
+ dispatchImeControlTargetChanged(mDisplayId, hasImeSourceControl);
+ }
+
+ if (hasImeSourceControl) {
+ final Point lastSurfacePosition = mImeSourceControl != null
+ ? mImeSourceControl.getSurfacePosition() : null;
+ final boolean positionChanged =
+ !imeSourceControl.getSurfacePosition().equals(lastSurfacePosition);
+ final boolean leashChanged =
+ !haveSameLeash(mImeSourceControl, imeSourceControl);
+ if (mAnimation != null) {
+ if (positionChanged) {
+ startAnimation(mImeShowing, true /* forceRestart */);
+ }
+ } else {
+ if (leashChanged) {
+ applyVisibilityToLeash(imeSourceControl);
+ }
+ if (!mImeShowing) {
+ removeImeSurface();
+ }
+ }
+ if (mImeSourceControl != null) {
+ mImeSourceControl.release(SurfaceControl::release);
+ }
+ mImeSourceControl = imeSourceControl;
+ }
}
- private void applyVisibilityToLeash() {
- SurfaceControl leash = mImeSourceControl.getLeash();
+ private void applyVisibilityToLeash(InsetsSourceControl imeSourceControl) {
+ SurfaceControl leash = imeSourceControl.getLeash();
if (leash != null) {
SurfaceControl.Transaction t = mTransactionPool.acquire();
if (mImeShowing) {
@@ -584,6 +602,15 @@
}
/**
+ * Called when the IME control target changed. So that the processor can restore its
+ * adjusted layout when the IME insets is not controlling by the current controller anymore.
+ *
+ * @param controlling indicates whether the current controller is controlling IME insets.
+ */
+ default void onImeControlTargetChanged(int displayId, boolean controlling) {
+ }
+
+ /**
* Called when the IME visibility changed.
*
* @param isShowing {@code true} if the IME is shown.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index e42f511..5b158d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -366,6 +366,7 @@
private final int mDisplayId;
+ private boolean mImeShown;
private int mYOffsetForIme;
private float mDimValue1;
private float mDimValue2;
@@ -392,6 +393,7 @@
if (!mInitialized || imeTargetPosition == SPLIT_POSITION_UNDEFINED) return 0;
mStartImeTop = showing ? hiddenTop : shownTop;
mEndImeTop = showing ? shownTop : hiddenTop;
+ mImeShown = showing;
// Update target dim values
mLastDim1 = mDimValue1;
@@ -414,7 +416,7 @@
mSplitWindowManager.setInteractive(
!showing || imeTargetPosition == SPLIT_POSITION_UNDEFINED);
- return 0;
+ return needOffset ? IME_ANIMATION_NO_ALPHA : 0;
}
@Override
@@ -432,6 +434,17 @@
mSplitLayoutHandler.onBoundsChanging(SplitLayout.this);
}
+ @Override
+ public void onImeControlTargetChanged(int displayId, boolean controlling) {
+ if (displayId != mDisplayId) return;
+ // Restore the split layout when wm-shell is not controlling IME insets anymore.
+ if (!controlling && mImeShown) {
+ reset();
+ mSplitWindowManager.setInteractive(true);
+ mSplitLayoutHandler.onBoundsChanging(SplitLayout.this);
+ }
+ }
+
private int getTargetYOffset() {
final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
// Make sure to keep at least 30% visible for the top split.
@@ -461,8 +474,10 @@
}
private void reset() {
- mYOffsetForIme = 0;
- mDimValue1 = mDimValue2 = 0.0f;
+ mImeShown = false;
+ mYOffsetForIme = mLastYOffset = mTargetYOffset = 0;
+ mDimValue1 = mLastDim1 = mTargetDim1 = 0.0f;
+ mDimValue2 = mLastDim2 = mTargetDim2 = 0.0f;
}
/* Adjust bounds with IME offset. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
index 23171bb..aced072 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
@@ -91,7 +91,6 @@
private boolean mPaused = true;
private boolean mPausedTargetAdjusted = false;
- private boolean mAdjustedWhileHidden = false;
DividerImeController(LegacySplitScreenTaskListener splits, TransactionPool pool,
ShellExecutor mainExecutor, TaskOrganizer taskOrganizer) {
@@ -123,7 +122,6 @@
void reset() {
mPaused = true;
mPausedTargetAdjusted = false;
- mAdjustedWhileHidden = false;
mAnimation = null;
mAdjusted = mTargetAdjusted = false;
mImeWasShown = mTargetShown = false;
@@ -140,6 +138,19 @@
? ADJUSTED_NONFOCUS_DIM : 0.f;
}
+
+ @Override
+ public void onImeControlTargetChanged(int displayId, boolean controlling) {
+ // Restore the split layout when wm-shell is not controlling IME insets anymore.
+ if (!controlling && mTargetShown) {
+ mPaused = false;
+ mTargetAdjusted = mTargetShown = false;
+ mTargetPrimaryDim = mTargetSecondaryDim = 0.f;
+ updateImeAdjustState(true /* force */);
+ startAsyncAnimation();
+ }
+ }
+
@Override
@ImeAnimationFlags
public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
@@ -151,8 +162,7 @@
mShownTop = shownTop;
mTargetShown = imeShouldShow;
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
- final boolean splitIsVisible = !getView().isHidden();
- final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
+ final boolean targetAdjusted = imeShouldShow && mSecondaryHasFocus
&& !imeIsFloating && !getLayout().mDisplayLayout.isLandscape()
&& !mSplits.mSplitScreenController.isMinimized();
if (mLastAdjustTop < 0) {
@@ -176,7 +186,7 @@
}
mTargetAdjusted = targetAdjusted;
updateDimTargets();
- if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState());
+ if (DEBUG) Slog.d(TAG, " ime starting. " + dumpState());
if (mAnimation != null || (mImeWasShown && imeShouldShow
&& mTargetAdjusted != mAdjusted)) {
// We need to animate adjustment independently of the IME position, so
@@ -184,13 +194,8 @@
// different split's editor has gained focus while the IME is still visible.
startAsyncAnimation();
}
- if (splitIsVisible) {
- // If split is hidden, we don't want to trigger any relayouts that would cause the
- // divider to show again.
- updateImeAdjustState();
- } else {
- mAdjustedWhileHidden = true;
- }
+ updateImeAdjustState();
+
return (mTargetAdjusted || mAdjusted) ? IME_ANIMATION_NO_ALPHA : 0;
}
@@ -256,11 +261,6 @@
mSplits.mSplitScreenController.setAdjustedForIme(mTargetShown && !mPaused);
}
- public void updateAdjustForIme() {
- updateImeAdjustState(mAdjustedWhileHidden);
- mAdjustedWhileHidden = false;
- }
-
@Override
public void onImePositionChanged(int displayId, int imeTop,
SurfaceControl.Transaction t) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
index ea2fc1a..80ab166 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
@@ -227,9 +227,6 @@
return;
}
mView.setHidden(showing);
- if (!showing) {
- mImePositionProcessor.updateAdjustForIme();
- }
mIsKeyguardShowing = showing;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index f0bd8a2..c816f18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -246,10 +246,20 @@
}
if (ev instanceof MotionEvent) {
+ MotionEvent mv = (MotionEvent) ev;
+ int action = mv.getActionMasked();
+ final Rect pipBounds = mPipBoundsState.getBounds();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ if (!pipBounds.contains((int) mv.getRawX(), (int) mv.getRawY())
+ && mPhonePipMenuController.isMenuVisible()) {
+ mPhonePipMenuController.hideMenu();
+ }
+ }
+
if (mEnablePinchResize && mOngoingPinchToResize) {
- onPinchResize((MotionEvent) ev);
+ onPinchResize(mv);
} else if (mEnableDragCornerResize) {
- onDragCornerResize((MotionEvent) ev);
+ onDragCornerResize(mv);
}
}
}
@@ -450,7 +460,6 @@
float x = ev.getX();
float y = ev.getY() - mOhmOffset;
if (action == MotionEvent.ACTION_DOWN) {
- final Rect currentPipBounds = mPipBoundsState.getBounds();
mLastResizeBounds.setEmpty();
mAllowGesture = isInValidSysUiState() && isWithinDragResizeRegion((int) x, (int) y);
if (mAllowGesture) {
@@ -458,11 +467,6 @@
mDownPoint.set(x, y);
mDownBounds.set(mPipBoundsState.getBounds());
}
- if (!currentPipBounds.contains((int) x, (int) y)
- && mPhonePipMenuController.isMenuVisible()) {
- mPhonePipMenuController.hideMenu();
- }
-
} else if (mAllowGesture) {
switch (action) {
case MotionEvent.ACTION_POINTER_DOWN:
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index f0995c4..b8fa55a 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -84,6 +84,8 @@
bool Properties::useHintManager = true;
int Properties::targetCpuTimePercentage = 70;
+bool Properties::enableWebViewOverlays = false;
+
StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI;
bool Properties::load() {
@@ -137,6 +139,8 @@
targetCpuTimePercentage = base::GetIntProperty(PROPERTY_TARGET_CPU_TIME_PERCENTAGE, 70);
if (targetCpuTimePercentage <= 0 || targetCpuTimePercentage > 100) targetCpuTimePercentage = 70;
+ enableWebViewOverlays = base::GetBoolProperty(PROPERTY_WEBVIEW_OVERLAYS_ENABLED, false);
+
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index f5fd003..7df6e2c 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -182,6 +182,11 @@
*/
#define PROPERTY_REDUCE_OPS_TASK_SPLITTING "renderthread.skia.reduceopstasksplitting"
+/**
+ * Enable WebView Overlays feature.
+ */
+#define PROPERTY_WEBVIEW_OVERLAYS_ENABLED "debug.hwui.webview_overlays_enabled"
+
///////////////////////////////////////////////////////////////////////////////
// Misc
///////////////////////////////////////////////////////////////////////////////
@@ -276,6 +281,8 @@
static bool useHintManager;
static int targetCpuTimePercentage;
+ static bool enableWebViewOverlays;
+
static StretchEffectBehavior getStretchEffectBehavior() {
return stretchEffectBehavior;
}
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 974c863..93f2f42 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -121,7 +121,7 @@
.mergeTransaction = currentFunctor.mergeTransaction,
};
- if (!drawInfo.isLayer) {
+ if (Properties::enableWebViewOverlays && !drawInfo.isLayer) {
renderthread::CanvasContext* activeContext =
renderthread::CanvasContext::getActiveContext();
if (activeContext != nullptr) {
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 4d31cd9..ef3a11c 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -933,6 +933,11 @@
env->ReleaseStringUTFChars(skiaDiskCachePath, skiaCacheArray);
}
+static jboolean android_view_ThreadedRenderer_isWebViewOverlaysEnabled(JNIEnv* env, jobject clazz) {
+ // this value is valid only after loadSystemProperties() is called
+ return Properties::enableWebViewOverlays;
+}
+
// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -1025,6 +1030,8 @@
(void*)android_view_ThreadedRenderer_setDisplayDensityDpi},
{"nInitDisplayInfo", "(IIFIJJ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo},
{"preload", "()V", (void*)android_view_ThreadedRenderer_preload},
+ {"isWebViewOverlaysEnabled", "()Z",
+ (void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled},
};
static JavaVM* mJvm = nullptr;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 5462623..44a6e43 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -59,6 +59,10 @@
}
bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
+ if (!mRenderThread.getGrContext()) {
+ ALOGD("Trying to pin an image with an invalid GrContext");
+ return false;
+ }
for (SkImage* image : mutableImages) {
if (SkImage_pinAsTexture(image, mRenderThread.getGrContext())) {
mPinnedImages.emplace_back(sk_ref_sp(image));
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 395a9a7..8b1e397 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -58,7 +58,9 @@
super.setContentView(R.layout.collapsing_toolbar_base_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mAppBarLayout = findViewById(R.id.app_bar);
- mAppBarLayout.addOnOffsetChangedListener(this);
+ if (mAppBarLayout != null) {
+ mAppBarLayout.addOnOffsetChangedListener(this);
+ }
if (savedInstanceState != null) {
mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
}
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 5f47be4..cb858c8 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -152,9 +152,6 @@
public void setTitle(CharSequence text) {
if (mTextView != null) {
mTextView.setText(text);
- if (mSwitch != null) {
- mSwitch.setContentDescription(mTextView.getText());
- }
}
}
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
index 80c95f5..139cd95 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -15,28 +15,30 @@
limitations under the License.
-->
-<layer-list
+<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:priv-android="http://schemas.android.com/apk/prv/res/android"
- android:paddingMode="stack">
+ android:color="@color/ripple_color">
- <item
- android:top="8dp"
- android:bottom="8dp">
- <shape>
- <corners
- android:radius="28dp"/>
- <solid
- android:color="?priv-android:attr/colorAccentPrimary"/>
- <size
- android:height="@dimen/spinner_height"/>
- </shape>
+ <item android:id="@android:id/background">
+ <layer-list android:paddingMode="stack">
+ <item
+ android:top="8dp"
+ android:bottom="8dp">
+
+ <shape>
+ <corners android:radius="28dp"/>
+ <solid android:color="?priv-android:attr/colorAccentPrimary"/>
+ <size android:height="@dimen/spinner_height"/>
+ </shape>
+ </item>
+
+ <item
+ android:gravity="center|end"
+ android:width="18dp"
+ android:height="18dp"
+ android:end="8dp"
+ android:drawable="@drawable/arrow_drop_down"/>
+ </layer-list>
</item>
-
- <item
- android:gravity="center|end"
- android:width="18dp"
- android:height="18dp"
- android:end="8dp"
- android:drawable="@drawable/arrow_drop_down"/>
-</layer-list>
\ No newline at end of file
+</ripple>
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
index 7bdf643..aa451ae 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2021 The Android Open Source Project
+ Copyright (C) 2018 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.
@@ -15,15 +15,14 @@
limitations under the License.
-->
-<layer-list
+<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:priv-android="http://schemas.android.com/apk/prv/res/android">
+ xmlns:priv-android="http://schemas.android.com/apk/prv/res/android"
+ android:color="@color/ripple_color">
- <item>
+ <item android:id="@android:id/background">
<shape>
- <solid
- android:color="?priv-android:attr/colorAccentSecondary"/>
+ <solid android:color="?priv-android:attr/colorAccentSecondary"/>
</shape>
</item>
-
-</layer-list>
\ No newline at end of file
+</ripple>
diff --git a/packages/SettingsLib/SettingsSpinner/res/values-night/colors.xml b/packages/SettingsLib/SettingsSpinner/res/values-night/colors.xml
new file mode 100644
index 0000000..abcf822
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<resources>
+ <color name="ripple_color">@*android:color/material_grey_900</color>
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/res/values/colors.xml b/packages/SettingsLib/SettingsSpinner/res/values/colors.xml
new file mode 100644
index 0000000..799b35e
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<resources>
+ <color name="ripple_color">?android:attr/colorControlHighlight</color>
+</resources>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
index 0845ca3..d86bd01 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.text.TextUtils;
import android.view.View;
import android.widget.Switch;
import android.widget.TextView;
@@ -59,13 +60,13 @@
}
@Test
- public void setTitle_switchShouldHasContentDescription() {
+ public void setTitle_switchShouldNotHasContentDescription() {
final String title = "title";
mBar.setTitle(title);
final Switch switchObj = mBar.getSwitch();
- assertThat(switchObj.getContentDescription()).isEqualTo(title);
+ assertThat(TextUtils.isEmpty(switchObj.getContentDescription())).isTrue();
}
@Test
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b357a94..d051290 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -94,6 +94,7 @@
"SystemUI-proto",
"dagger2",
"jsr330",
+ "lottie",
],
manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index de2eca2..bd2209b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -35,7 +35,7 @@
String ACTION = "com.android.systemui.action.PLUGIN_QS";
- int VERSION = 10;
+ int VERSION = 11;
String TAG = "QS";
@@ -108,6 +108,20 @@
*/
void setCollapsedMediaVisibilityChangedListener(Consumer<Boolean> listener);
+ /**
+ * Set a scroll listener for the QSPanel container
+ */
+ default void setScrollListener(ScrollListener scrollListener) {}
+
+ /**
+ * Callback for when QSPanel container is scrolled
+ */
+ @ProvidesInterface(version = ScrollListener.VERSION)
+ interface ScrollListener {
+ int VERSION = 1;
+ void onQsPanelScrollChanged(int scrollY);
+ }
+
@ProvidesInterface(version = HeightListener.VERSION)
interface HeightListener {
int VERSION = 1;
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 9811434..29fcf57 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -57,7 +57,7 @@
android:id="@+id/animatable_clock_view_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
+ android:layout_gravity="center"
android:gravity="center_horizontal"
android:textSize="@dimen/large_clock_text_size"
android:fontFamily="@font/clock"
diff --git a/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
index 2f8f11d..def7b31 100644
--- a/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
+++ b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
@@ -17,21 +17,12 @@
*/
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <group>
- <clip-path
- android:pathData="M2.15,1.54h20v21h-20z"/>
- <path
- android:pathData="M19,21.83H5.35a3.19,3.19 0,0 1,-3.2 -3.19v-7A3.19,3.19 0,0 1,5.35 8.5H19a3.19,3.19 0,0 1,3.19 3.19v7A3.19,3.19 0,0 1,19 21.83ZM5.35,10.44A1.25,1.25 0,0 0,4.1 11.69v7a1.25,1.25 0,0 0,1.25 1.24H19a1.25,1.25 0,0 0,1.25 -1.24v-7A1.25,1.25 0,0 0,19 10.44Z"
- android:fillColor="#FF000000" />
- <path
- android:pathData="M4.7,10.16 L4.21,8.57 16,5a3.56,3.56 0,0 1,3.1 0.25c1,0.67 1.65,2 1.89,4l-1.66,0.2C19.12,8 18.72,7 18.15,6.62a2,2 0,0 0,-1.7 0Z"
- android:fillColor="#FF000000" />
- <path
- android:pathData="M4.43,10.47l-1,-1.34 7.31,-5.44c3,-1.86 5.51,1 6.33,2L15.82,6.77c-2.1,-2.44 -3.23,-2.26 -4.14,-1.7Z"
- android:fillColor="#FF000000" />
- </group>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20,4L4,4c-1.11,0 -1.99,0.89 -1.99,2L2,18c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,6c0,-1.11 -0.89,-2 -2,-2zM20,18L4,18v-6h16v6zM20,8L4,8L4,6h16v2z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/wallet_app_button_bg.xml b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
index 1136b9d..ecf09c2 100644
--- a/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
+++ b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
@@ -14,10 +14,11 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item>
<shape android:shape="rectangle">
- <stroke android:width="1dp" android:color="@color/GM2_grey_300"/>
+ <stroke android:width="1dp" android:color="?androidprv:attr/colorAccentSecondary"/>
<solid android:color="@android:color/transparent"/>
<corners android:radius="24dp"/>
</shape>
diff --git a/packages/SystemUI/res/layout/people_tile_small_horizontal.xml b/packages/SystemUI/res/layout/people_tile_small_horizontal.xml
new file mode 100644
index 0000000..950d7ac
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_tile_small_horizontal.xml
@@ -0,0 +1,79 @@
+<?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.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:id="@android:id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:background="@drawable/people_space_tile_view_card"
+ android:clipToOutline="true"
+ android:orientation="horizontal"
+ android:paddingHorizontal="8dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="6dp">
+
+ <ImageView
+ android:id="@+id/person_icon"
+ android:layout_gravity="start|center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingEnd="4dp"/>
+
+ <ImageView
+ android:id="@+id/predefined_icon"
+ android:layout_weight="1"
+ android:tint="?android:attr/textColorSecondary"
+ android:layout_gravity="start|center_vertical"
+ android:layout_width="18dp"
+ android:layout_height="18dp" />
+
+ <TextView
+ android:id="@+id/messages_count"
+ android:layout_weight="1"
+ android:layout_gravity="start|center_vertical"
+ android:gravity="center"
+ android:paddingHorizontal="8dp"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+ android:textColor="?androidprv:attr/textColorOnAccent"
+ android:background="@drawable/people_space_messages_count_background"
+ android:textSize="@dimen/name_text_size_for_small"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ />
+
+ <TextView
+ android:id="@+id/name"
+ android:layout_weight="1"
+ android:layout_gravity="start|center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="@dimen/name_text_size_for_small" />
+ </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view.xml b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
index 562040b..33baa4e 100644
--- a/packages/SystemUI/res/layout/udfps_keyguard_view.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
@@ -16,6 +16,7 @@
-->
<com.android.systemui.biometrics.UdfpsKeyguardView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -29,8 +30,28 @@
android:visibility="gone"/>
<!-- Fingerprint -->
- <ImageView
- android:id="@+id/udfps_keyguard_animation_fp_view"
+
+ <!-- AOD dashed fingerprint icon with moving dashes -->
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/udfps_aod_fp"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:scaleType="centerCrop"
+ app:lottie_autoPlay="false"
+ android:padding="16dp"
+ app:lottie_loop="true"
+ app:lottie_rawRes="@raw/udfps_aod_fp"/>
+
+ <!-- LockScreen fingerprint icon from 0 stroke width to full width -->
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/udfps_lockscreen_fp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:scaleType="centerCrop"
+ app:lottie_autoPlay="false"
+ app:lottie_loop="false"
+ android:padding="16dp"
+ app:lottie_rawRes="@raw/udfps_lockscreen_fp"/>
</com.android.systemui.biometrics.UdfpsKeyguardView>
diff --git a/packages/SystemUI/res/layout/wallet_fullscreen.xml b/packages/SystemUI/res/layout/wallet_fullscreen.xml
index 71006f0..1dd400a 100644
--- a/packages/SystemUI/res/layout/wallet_fullscreen.xml
+++ b/packages/SystemUI/res/layout/wallet_fullscreen.xml
@@ -27,12 +27,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
- android:navigationContentDescription="@null" />
+ android:navigationContentDescription="@null">
+ <Button
+ android:id="@+id/wallet_toolbar_app_button"
+ android:layout_width="wrap_content"
+ android:layout_height="30dp"
+ android:layout_gravity="end|center_horizontal"
+ android:paddingHorizontal="@dimen/wallet_button_horizontal_padding"
+ android:background="@drawable/wallet_app_button_bg"
+ android:text="@string/wallet_app_button_label"
+ android:textColor="?androidprv:attr/colorAccentPrimary"
+ android:textAlignment="center"
+ android:visibility="gone"/>
+ </Toolbar>
<LinearLayout
android:id="@+id/card_carousel_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="48dp"
+ android:layout_marginTop="@dimen/wallet_card_carousel_container_top_margin"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@@ -54,6 +66,7 @@
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginBottom="24dp"
android:layout_marginHorizontal="48dp"
android:textColor="?androidprv:attr/textColorPrimary"
android:textAlignment="center"/>
@@ -67,7 +80,7 @@
android:transitionName="dotIndicator"
android:clipChildren="false"
android:clipToPadding="false"
- android:layout_marginVertical="24dp"/>
+ android:layout_marginBottom="24dp"/>
<Button
android:id="@+id/wallet_action_button"
android:layout_width="wrap_content"
@@ -83,6 +96,7 @@
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<View
+ android:id="@+id/dynamic_placeholder"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"/>
diff --git a/packages/SystemUI/res/raw/udfps_aod_fp.json b/packages/SystemUI/res/raw/udfps_aod_fp.json
new file mode 100644
index 0000000..cdac332
--- /dev/null
+++ b/packages/SystemUI/res/raw/udfps_aod_fp.json
@@ -0,0 +1,2445 @@
+{
+ "v": "5.7.8",
+ "fr": 60,
+ "ip": 0,
+ "op": 361,
+ "w": 180,
+ "h": 185,
+ "nm": "fingerprint_burn_in_Loop",
+ "ddd": 0,
+ "assets": [],
+ "layers": [
+ {
+ "ddd": 0,
+ "ind": 1,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 10",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -3.684,
+ 0
+ ],
+ [
+ -2.883,
+ -1.583
+ ]
+ ],
+ "o": [
+ [
+ 2.883,
+ -1.583
+ ],
+ [
+ 3.683,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -10.417,
+ 1.25
+ ],
+ [
+ 0.001,
+ -1.25
+ ],
+ [
+ 10.417,
+ 1.25
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 17,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 246
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 1326
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.999,
+ 7.5
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 3",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 2,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 5",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -3.684,
+ 0
+ ],
+ [
+ -2.883,
+ -1.583
+ ]
+ ],
+ "o": [
+ [
+ 2.883,
+ -1.583
+ ],
+ [
+ 3.683,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -10.417,
+ 1.25
+ ],
+ [
+ 0.001,
+ -1.25
+ ],
+ [
+ 10.417,
+ 1.25
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 54,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 1080
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.999,
+ 7.5
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 3",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 3,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 8",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.883,
+ 0
+ ],
+ [
+ -2.367,
+ -3.933
+ ]
+ ],
+ "o": [
+ [
+ 2.367,
+ -3.933
+ ],
+ [
+ 5.883,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -13.75,
+ 3.333
+ ],
+ [
+ 0,
+ -3.333
+ ],
+ [
+ 13.75,
+ 3.333
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 38.235,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 170
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 890
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 20,
+ 16.25
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 4,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 4",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.883,
+ 0
+ ],
+ [
+ -2.367,
+ -3.933
+ ]
+ ],
+ "o": [
+ [
+ 2.367,
+ -3.933
+ ],
+ [
+ 5.883,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -13.75,
+ 3.333
+ ],
+ [
+ 0,
+ -3.333
+ ],
+ [
+ 13.75,
+ 3.333
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 34.235,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 720
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 20,
+ 16.25
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 5,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 7",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -6.65,
+ 0
+ ],
+ [
+ 0,
+ -5.9
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 2.333,
+ 0
+ ],
+ [
+ 0.633,
+ 1.601
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.717,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -2.2
+ ],
+ [
+ -2.15,
+ -1.716
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ -0.767,
+ -2.134
+ ],
+ [
+ 0,
+ -5.917
+ ],
+ [
+ 6.65,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 2.333
+ ],
+ [
+ -1.734,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.634,
+ -1.599
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -2.2,
+ 0
+ ],
+ [
+ 0,
+ 2.75
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -11.108,
+ 5.825
+ ],
+ [
+ -11.875,
+ 1.525
+ ],
+ [
+ -0.208,
+ -9.175
+ ],
+ [
+ 11.875,
+ 1.525
+ ],
+ [
+ 11.875,
+ 1.592
+ ],
+ [
+ 7.659,
+ 5.808
+ ],
+ [
+ 3.742,
+ 3.158
+ ],
+ [
+ 2.526,
+ 0.141
+ ],
+ [
+ -1.391,
+ -2.508
+ ],
+ [
+ -1.641,
+ -2.508
+ ],
+ [
+ -5.625,
+ 1.475
+ ],
+ [
+ -2.225,
+ 8.558
+ ],
+ [
+ -1.458,
+ 9.175
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 35,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ -159
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 201
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.992,
+ 28.758
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 4",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 6,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 6",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -6.65,
+ 0
+ ],
+ [
+ 0,
+ -5.9
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 2.333,
+ 0
+ ],
+ [
+ 0.633,
+ 1.601
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.717,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -2.2
+ ],
+ [
+ -2.15,
+ -1.716
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ -0.767,
+ -2.134
+ ],
+ [
+ 0,
+ -5.917
+ ],
+ [
+ 6.65,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 2.333
+ ],
+ [
+ -1.734,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.634,
+ -1.599
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -2.2,
+ 0
+ ],
+ [
+ 0,
+ 2.75
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -11.108,
+ 5.825
+ ],
+ [
+ -11.875,
+ 1.525
+ ],
+ [
+ -0.208,
+ -9.175
+ ],
+ [
+ 11.875,
+ 1.525
+ ],
+ [
+ 11.875,
+ 1.592
+ ],
+ [
+ 7.659,
+ 5.808
+ ],
+ [
+ 3.742,
+ 3.158
+ ],
+ [
+ 2.526,
+ 0.141
+ ],
+ [
+ -1.391,
+ -2.508
+ ],
+ [
+ -1.641,
+ -2.508
+ ],
+ [
+ -5.625,
+ 1.475
+ ],
+ [
+ -2.225,
+ 8.558
+ ],
+ [
+ -1.458,
+ 9.175
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 9,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 135
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 495
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.992,
+ 28.758
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 4",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 7,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 3",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -6.65,
+ 0
+ ],
+ [
+ 0,
+ -5.9
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 2.333,
+ 0
+ ],
+ [
+ 0.633,
+ 1.601
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.717,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -2.2
+ ],
+ [
+ -2.15,
+ -1.716
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ -0.767,
+ -2.134
+ ],
+ [
+ 0,
+ -5.917
+ ],
+ [
+ 6.65,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 2.333
+ ],
+ [
+ -1.734,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.634,
+ -1.599
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -2.2,
+ 0
+ ],
+ [
+ 0,
+ 2.75
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -11.108,
+ 5.825
+ ],
+ [
+ -11.875,
+ 1.525
+ ],
+ [
+ -0.208,
+ -9.175
+ ],
+ [
+ 11.875,
+ 1.525
+ ],
+ [
+ 11.875,
+ 1.592
+ ],
+ [
+ 7.659,
+ 5.808
+ ],
+ [
+ 3.742,
+ 3.158
+ ],
+ [
+ 2.526,
+ 0.141
+ ],
+ [
+ -1.391,
+ -2.508
+ ],
+ [
+ -1.641,
+ -2.508
+ ],
+ [
+ -5.625,
+ 1.475
+ ],
+ [
+ -2.225,
+ 8.558
+ ],
+ [
+ -1.458,
+ 9.175
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 30,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 360
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.992,
+ 28.758
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 4",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 8,
+ "ty": 4,
+ "nm": "Layer 1 Outlines 2",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 3.2,
+ 0
+ ],
+ [
+ 2.217,
+ 2.066
+ ]
+ ],
+ "o": [
+ [
+ -2.217,
+ 2.066
+ ],
+ [
+ -3.2,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 8.75,
+ -1.667
+ ],
+ [
+ 0,
+ 1.667
+ ],
+ [
+ -8.75,
+ -1.667
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 69,
+ "ix": 2
+ },
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 0.833
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 360,
+ "s": [
+ 720
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 1,
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "d": [
+ {
+ "n": "d",
+ "nm": "dash",
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ }
+ },
+ {
+ "n": "o",
+ "nm": "offset",
+ "v": {
+ "a": 0,
+ "k": 25,
+ "ix": 7
+ }
+ }
+ ],
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 20,
+ 42.083
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ }
+ ],
+ "markers": [
+ {
+ "tm": 210,
+ "cm": "2",
+ "dr": 0
+ },
+ {
+ "tm": 255,
+ "cm": "1",
+ "dr": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/udfps_lockscreen_fp.json b/packages/SystemUI/res/raw/udfps_lockscreen_fp.json
new file mode 100644
index 0000000..cef433e
--- /dev/null
+++ b/packages/SystemUI/res/raw/udfps_lockscreen_fp.json
@@ -0,0 +1,1017 @@
+{
+ "v": "5.7.8",
+ "fr": 60,
+ "ip": 0,
+ "op": 46,
+ "w": 180,
+ "h": 185,
+ "nm": "fingerprint_build_on",
+ "ddd": 0,
+ "assets": [],
+ "layers": [
+ {
+ "ddd": 0,
+ "ind": 1,
+ "ty": 4,
+ "nm": "fingerprint_build_on",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 91.456,
+ 92.206,
+ 0
+ ],
+ "ix": 2,
+ "l": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 20,
+ 25,
+ 0
+ ],
+ "ix": 1,
+ "l": 2
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 350,
+ 350,
+ 100
+ ],
+ "ix": 6,
+ "l": 2
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 3.2,
+ 0
+ ],
+ [
+ 2.217,
+ 2.066
+ ]
+ ],
+ "o": [
+ [
+ -2.217,
+ 2.066
+ ],
+ [
+ -3.2,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 8.75,
+ -1.667
+ ],
+ [
+ 0,
+ 1.667
+ ],
+ [
+ -8.75,
+ -1.667
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 100,
+ "ix": 2
+ },
+ "o": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 24,
+ "s": [
+ 2.5
+ ]
+ }
+ ],
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "d": [
+ {
+ "n": "d",
+ "nm": "dash",
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ }
+ },
+ {
+ "n": "o",
+ "nm": "offset",
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 7
+ }
+ }
+ ],
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 20,
+ 42.083
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.883,
+ 0
+ ],
+ [
+ -2.367,
+ -3.933
+ ]
+ ],
+ "o": [
+ [
+ 2.367,
+ -3.933
+ ],
+ [
+ 5.883,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -13.75,
+ 3.333
+ ],
+ [
+ 0,
+ -3.333
+ ],
+ [
+ 13.75,
+ 3.333
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 100,
+ "ix": 2
+ },
+ "o": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 24,
+ "s": [
+ 2.5
+ ]
+ }
+ ],
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 20,
+ 16.25
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -3.684,
+ 0
+ ],
+ [
+ -2.883,
+ -1.583
+ ]
+ ],
+ "o": [
+ [
+ 2.883,
+ -1.583
+ ],
+ [
+ 3.683,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -10.417,
+ 1.25
+ ],
+ [
+ 0.001,
+ -1.25
+ ],
+ [
+ 10.417,
+ 1.25
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 100,
+ "ix": 2
+ },
+ "o": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 24,
+ "s": [
+ 2.5
+ ]
+ }
+ ],
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.999,
+ 7.5
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 3",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 3,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -6.65,
+ 0
+ ],
+ [
+ 0,
+ -5.9
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 2.333,
+ 0
+ ],
+ [
+ 0.633,
+ 1.601
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.717,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -2.2
+ ],
+ [
+ -2.15,
+ -1.716
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ -0.767,
+ -2.134
+ ],
+ [
+ 0,
+ -5.917
+ ],
+ [
+ 6.65,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 2.333
+ ],
+ [
+ -1.734,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.634,
+ -1.599
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -2.2,
+ 0
+ ],
+ [
+ 0,
+ 2.75
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -11.108,
+ 5.825
+ ],
+ [
+ -11.875,
+ 1.525
+ ],
+ [
+ -0.208,
+ -9.175
+ ],
+ [
+ 11.875,
+ 1.525
+ ],
+ [
+ 11.875,
+ 1.592
+ ],
+ [
+ 7.659,
+ 5.808
+ ],
+ [
+ 3.742,
+ 3.158
+ ],
+ [
+ 2.526,
+ 0.141
+ ],
+ [
+ -1.391,
+ -2.508
+ ],
+ [
+ -1.641,
+ -2.508
+ ],
+ [
+ -5.625,
+ 1.475
+ ],
+ [
+ -2.225,
+ 8.558
+ ],
+ [
+ -1.458,
+ 9.175
+ ]
+ ],
+ "c": false
+ },
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "a": 0,
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "a": 0,
+ "k": 100,
+ "ix": 2
+ },
+ "o": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1",
+ "mn": "ADBE Vector Filter - Trim",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0.167
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "t": 24,
+ "s": [
+ 2.5
+ ]
+ }
+ ],
+ "ix": 5
+ },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 19.992,
+ 28.758
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 4",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 4,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 600,
+ "st": 0,
+ "bm": 0
+ }
+ ],
+ "markers": [
+ {
+ "tm": 210,
+ "cm": "2",
+ "dr": 0
+ },
+ {
+ "tm": 255,
+ "cm": "1",
+ "dr": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
new file mode 100644
index 0000000..85d9393
--- /dev/null
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Не е налице"</item>
+ <item msgid="3048856902433862868">"Изкл."</item>
+ <item msgid="6877982264300789870">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Не е налице"</item>
+ <item msgid="4293012229142257455">"Изкл."</item>
+ <item msgid="6221288736127914861">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Не е налице"</item>
+ <item msgid="2074416252859094119">"Изкл."</item>
+ <item msgid="287997784730044767">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Не е налице"</item>
+ <item msgid="7838121007534579872">"Изкл."</item>
+ <item msgid="1578872232501319194">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Не е налице"</item>
+ <item msgid="5376619709702103243">"Изкл."</item>
+ <item msgid="4875147066469902392">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Не е налице"</item>
+ <item msgid="5044688398303285224">"Изкл."</item>
+ <item msgid="8527389108867454098">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Не е налице"</item>
+ <item msgid="5776427577477729185">"Изкл."</item>
+ <item msgid="7105052717007227415">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Не е налице"</item>
+ <item msgid="5315121904534729843">"Изкл."</item>
+ <item msgid="503679232285959074">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Не е налице"</item>
+ <item msgid="4801037224991420996">"Изкл."</item>
+ <item msgid="1982293347302546665">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Не е налице"</item>
+ <item msgid="4813655083852587017">"Изкл."</item>
+ <item msgid="6744077414775180687">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Не е налице"</item>
+ <item msgid="5715725170633593906">"Изкл."</item>
+ <item msgid="2075645297847971154">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Не е налице"</item>
+ <item msgid="9103697205127645916">"Изкл."</item>
+ <item msgid="8067744885820618230">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Не е налице"</item>
+ <item msgid="6983679487661600728">"Изкл."</item>
+ <item msgid="7520663805910678476">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Не е налице"</item>
+ <item msgid="400477985171353">"Изкл."</item>
+ <item msgid="630890598801118771">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Не е налице"</item>
+ <item msgid="8045580926543311193">"Изкл."</item>
+ <item msgid="4913460972266982499">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Не е налице"</item>
+ <item msgid="1488620600954313499">"Изкл."</item>
+ <item msgid="588467578853244035">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Не е налице"</item>
+ <item msgid="2744885441164350155">"Изкл."</item>
+ <item msgid="151121227514952197">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Не е налице"</item>
+ <item msgid="8259411607272330225">"Изкл."</item>
+ <item msgid="578444932039713369">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Не е налице"</item>
+ <item msgid="8707481475312432575">"Изкл."</item>
+ <item msgid="8031106212477483874">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Не е налице"</item>
+ <item msgid="4572245614982283078">"Изкл."</item>
+ <item msgid="6536448410252185664">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Не е налице"</item>
+ <item msgid="4765607635752003190">"Изкл."</item>
+ <item msgid="1697460731949649844">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Не е налице"</item>
+ <item msgid="3296179158646568218">"Изкл."</item>
+ <item msgid="8998632451221157987">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Не е налице"</item>
+ <item msgid="4544919905196727508">"Изкл."</item>
+ <item msgid="3422023746567004609">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Не е налице"</item>
+ <item msgid="7571394439974244289">"Изкл."</item>
+ <item msgid="6866424167599381915">"Вкл."</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Не е налице"</item>
+ <item msgid="2710157085538036590">"Изкл."</item>
+ <item msgid="7809470840976856149">"Вкл."</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
new file mode 100644
index 0000000..5622a82
--- /dev/null
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Nedostupno"</item>
+ <item msgid="3048856902433862868">"Isključeno"</item>
+ <item msgid="6877982264300789870">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Nedostupno"</item>
+ <item msgid="4293012229142257455">"Isključeno"</item>
+ <item msgid="6221288736127914861">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Nedostupno"</item>
+ <item msgid="2074416252859094119">"Isključeno"</item>
+ <item msgid="287997784730044767">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Nedostupno"</item>
+ <item msgid="7838121007534579872">"Isključeno"</item>
+ <item msgid="1578872232501319194">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Nedostupno"</item>
+ <item msgid="5376619709702103243">"Isključeno"</item>
+ <item msgid="4875147066469902392">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Nedostupno"</item>
+ <item msgid="5044688398303285224">"Isključeno"</item>
+ <item msgid="8527389108867454098">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Nedostupno"</item>
+ <item msgid="5776427577477729185">"Isključeno"</item>
+ <item msgid="7105052717007227415">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Nedostupno"</item>
+ <item msgid="5315121904534729843">"Isključeno"</item>
+ <item msgid="503679232285959074">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Nedostupno"</item>
+ <item msgid="4801037224991420996">"Isključeno"</item>
+ <item msgid="1982293347302546665">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Nedostupno"</item>
+ <item msgid="4813655083852587017">"Isključeno"</item>
+ <item msgid="6744077414775180687">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Nedostupno"</item>
+ <item msgid="5715725170633593906">"Isključeno"</item>
+ <item msgid="2075645297847971154">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Nedostupno"</item>
+ <item msgid="9103697205127645916">"Isključeno"</item>
+ <item msgid="8067744885820618230">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Nedostupno"</item>
+ <item msgid="6983679487661600728">"Isključeno"</item>
+ <item msgid="7520663805910678476">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Nedostupno"</item>
+ <item msgid="400477985171353">"Isključeno"</item>
+ <item msgid="630890598801118771">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Nedostupno"</item>
+ <item msgid="8045580926543311193">"Isključeno"</item>
+ <item msgid="4913460972266982499">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Nedostupno"</item>
+ <item msgid="1488620600954313499">"Isključeno"</item>
+ <item msgid="588467578853244035">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Nedostupno"</item>
+ <item msgid="2744885441164350155">"Isključeno"</item>
+ <item msgid="151121227514952197">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Nedostupno"</item>
+ <item msgid="8259411607272330225">"Isključeno"</item>
+ <item msgid="578444932039713369">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Nedostupno"</item>
+ <item msgid="8707481475312432575">"Isključeno"</item>
+ <item msgid="8031106212477483874">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Nedostupno"</item>
+ <item msgid="4572245614982283078">"Isključeno"</item>
+ <item msgid="6536448410252185664">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Nedostupno"</item>
+ <item msgid="4765607635752003190">"Isključeno"</item>
+ <item msgid="1697460731949649844">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Nedostupno"</item>
+ <item msgid="3296179158646568218">"Isključeno"</item>
+ <item msgid="8998632451221157987">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Nedostupno"</item>
+ <item msgid="4544919905196727508">"Isključeno"</item>
+ <item msgid="3422023746567004609">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Nedostupno"</item>
+ <item msgid="7571394439974244289">"Isključeno"</item>
+ <item msgid="6866424167599381915">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Nedostupno"</item>
+ <item msgid="2710157085538036590">"Isključeno"</item>
+ <item msgid="7809470840976856149">"Uključeno"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
new file mode 100644
index 0000000..0496502
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Unavailable"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Unavailable"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Unavailable"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Unavailable"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Unavailable"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Unavailable"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Unavailable"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Unavailable"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Unavailable"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Unavailable"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Unavailable"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Unavailable"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Unavailable"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Unavailable"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Unavailable"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Unavailable"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Unavailable"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Unavailable"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Unavailable"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Unavailable"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Unavailable"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Unavailable"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Unavailable"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Unavailable"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Unavailable"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
new file mode 100644
index 0000000..0496502
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Unavailable"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Unavailable"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Unavailable"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Unavailable"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Unavailable"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Unavailable"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Unavailable"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Unavailable"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Unavailable"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Unavailable"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Unavailable"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Unavailable"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Unavailable"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Unavailable"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Unavailable"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Unavailable"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Unavailable"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Unavailable"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Unavailable"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Unavailable"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Unavailable"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Unavailable"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Unavailable"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Unavailable"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Unavailable"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
new file mode 100644
index 0000000..0496502
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Unavailable"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Unavailable"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Unavailable"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Unavailable"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Unavailable"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Unavailable"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Unavailable"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Unavailable"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Unavailable"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Unavailable"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Unavailable"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Unavailable"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Unavailable"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Unavailable"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Unavailable"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Unavailable"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Unavailable"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Unavailable"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Unavailable"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Unavailable"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Unavailable"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Unavailable"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Unavailable"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Unavailable"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Unavailable"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
new file mode 100644
index 0000000..0496502
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Unavailable"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Unavailable"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Unavailable"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Unavailable"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Unavailable"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Unavailable"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Unavailable"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Unavailable"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Unavailable"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Unavailable"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Unavailable"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Unavailable"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Unavailable"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Unavailable"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Unavailable"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Unavailable"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Unavailable"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Unavailable"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Unavailable"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Unavailable"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Unavailable"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Unavailable"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Unavailable"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Unavailable"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Unavailable"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
new file mode 100644
index 0000000..3bc03c0
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Unavailable"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Unavailable"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Unavailable"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Unavailable"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Unavailable"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Unavailable"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Unavailable"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Unavailable"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Unavailable"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Unavailable"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Unavailable"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Unavailable"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Unavailable"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Unavailable"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Unavailable"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Unavailable"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Unavailable"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Unavailable"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Unavailable"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Unavailable"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Unavailable"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Unavailable"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Unavailable"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Unavailable"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Unavailable"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
new file mode 100644
index 0000000..6e6c148
--- /dev/null
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"No disponible"</item>
+ <item msgid="3048856902433862868">"No"</item>
+ <item msgid="6877982264300789870">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"No disponible"</item>
+ <item msgid="4293012229142257455">"No"</item>
+ <item msgid="6221288736127914861">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"No disponible"</item>
+ <item msgid="2074416252859094119">"No"</item>
+ <item msgid="287997784730044767">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"No disponible"</item>
+ <item msgid="7838121007534579872">"No"</item>
+ <item msgid="1578872232501319194">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"No disponible"</item>
+ <item msgid="5376619709702103243">"No"</item>
+ <item msgid="4875147066469902392">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"No disponible"</item>
+ <item msgid="5044688398303285224">"No"</item>
+ <item msgid="8527389108867454098">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"No disponible"</item>
+ <item msgid="5776427577477729185">"No"</item>
+ <item msgid="7105052717007227415">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"No disponible"</item>
+ <item msgid="5315121904534729843">"No"</item>
+ <item msgid="503679232285959074">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"No disponible"</item>
+ <item msgid="4801037224991420996">"No"</item>
+ <item msgid="1982293347302546665">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"No disponible"</item>
+ <item msgid="4813655083852587017">"No"</item>
+ <item msgid="6744077414775180687">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"No disponible"</item>
+ <item msgid="5715725170633593906">"No"</item>
+ <item msgid="2075645297847971154">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"No disponible"</item>
+ <item msgid="9103697205127645916">"No"</item>
+ <item msgid="8067744885820618230">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"No disponible"</item>
+ <item msgid="6983679487661600728">"No"</item>
+ <item msgid="7520663805910678476">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"No disponible"</item>
+ <item msgid="400477985171353">"No"</item>
+ <item msgid="630890598801118771">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"No disponible"</item>
+ <item msgid="8045580926543311193">"No"</item>
+ <item msgid="4913460972266982499">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"No disponible"</item>
+ <item msgid="1488620600954313499">"No"</item>
+ <item msgid="588467578853244035">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"No disponible"</item>
+ <item msgid="2744885441164350155">"No"</item>
+ <item msgid="151121227514952197">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"No disponible"</item>
+ <item msgid="8259411607272330225">"No"</item>
+ <item msgid="578444932039713369">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"No disponible"</item>
+ <item msgid="8707481475312432575">"No"</item>
+ <item msgid="8031106212477483874">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"No disponible"</item>
+ <item msgid="4572245614982283078">"No"</item>
+ <item msgid="6536448410252185664">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"No disponible"</item>
+ <item msgid="4765607635752003190">"No"</item>
+ <item msgid="1697460731949649844">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"No disponible"</item>
+ <item msgid="3296179158646568218">"No"</item>
+ <item msgid="8998632451221157987">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"No disponible"</item>
+ <item msgid="4544919905196727508">"No"</item>
+ <item msgid="3422023746567004609">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"No disponible"</item>
+ <item msgid="7571394439974244289">"No"</item>
+ <item msgid="6866424167599381915">"Sí"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"No disponible"</item>
+ <item msgid="2710157085538036590">"No"</item>
+ <item msgid="7809470840976856149">"Sí"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml
index cfacbec..19ec8ce 100644
--- a/packages/SystemUI/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/res/values-h800dp/dimens.xml
@@ -20,4 +20,7 @@
<!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
<dimen name="large_clock_text_size">200dp</dimen>
+
+ <!-- With the large clock, move up slightly from the center -->
+ <dimen name="keyguard_large_clock_top_margin">-104dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
new file mode 100644
index 0000000..5622a82
--- /dev/null
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Nedostupno"</item>
+ <item msgid="3048856902433862868">"Isključeno"</item>
+ <item msgid="6877982264300789870">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Nedostupno"</item>
+ <item msgid="4293012229142257455">"Isključeno"</item>
+ <item msgid="6221288736127914861">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Nedostupno"</item>
+ <item msgid="2074416252859094119">"Isključeno"</item>
+ <item msgid="287997784730044767">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Nedostupno"</item>
+ <item msgid="7838121007534579872">"Isključeno"</item>
+ <item msgid="1578872232501319194">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Nedostupno"</item>
+ <item msgid="5376619709702103243">"Isključeno"</item>
+ <item msgid="4875147066469902392">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Nedostupno"</item>
+ <item msgid="5044688398303285224">"Isključeno"</item>
+ <item msgid="8527389108867454098">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Nedostupno"</item>
+ <item msgid="5776427577477729185">"Isključeno"</item>
+ <item msgid="7105052717007227415">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Nedostupno"</item>
+ <item msgid="5315121904534729843">"Isključeno"</item>
+ <item msgid="503679232285959074">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Nedostupno"</item>
+ <item msgid="4801037224991420996">"Isključeno"</item>
+ <item msgid="1982293347302546665">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Nedostupno"</item>
+ <item msgid="4813655083852587017">"Isključeno"</item>
+ <item msgid="6744077414775180687">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Nedostupno"</item>
+ <item msgid="5715725170633593906">"Isključeno"</item>
+ <item msgid="2075645297847971154">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Nedostupno"</item>
+ <item msgid="9103697205127645916">"Isključeno"</item>
+ <item msgid="8067744885820618230">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Nedostupno"</item>
+ <item msgid="6983679487661600728">"Isključeno"</item>
+ <item msgid="7520663805910678476">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Nedostupno"</item>
+ <item msgid="400477985171353">"Isključeno"</item>
+ <item msgid="630890598801118771">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Nedostupno"</item>
+ <item msgid="8045580926543311193">"Isključeno"</item>
+ <item msgid="4913460972266982499">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Nedostupno"</item>
+ <item msgid="1488620600954313499">"Isključeno"</item>
+ <item msgid="588467578853244035">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Nedostupno"</item>
+ <item msgid="2744885441164350155">"Isključeno"</item>
+ <item msgid="151121227514952197">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Nedostupno"</item>
+ <item msgid="8259411607272330225">"Isključeno"</item>
+ <item msgid="578444932039713369">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Nedostupno"</item>
+ <item msgid="8707481475312432575">"Isključeno"</item>
+ <item msgid="8031106212477483874">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Nedostupno"</item>
+ <item msgid="4572245614982283078">"Isključeno"</item>
+ <item msgid="6536448410252185664">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Nedostupno"</item>
+ <item msgid="4765607635752003190">"Isključeno"</item>
+ <item msgid="1697460731949649844">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Nedostupno"</item>
+ <item msgid="3296179158646568218">"Isključeno"</item>
+ <item msgid="8998632451221157987">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Nedostupno"</item>
+ <item msgid="4544919905196727508">"Isključeno"</item>
+ <item msgid="3422023746567004609">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Nedostupno"</item>
+ <item msgid="7571394439974244289">"Isključeno"</item>
+ <item msgid="6866424167599381915">"Uključeno"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Nedostupno"</item>
+ <item msgid="2710157085538036590">"Isključeno"</item>
+ <item msgid="7809470840976856149">"Uključeno"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
new file mode 100644
index 0000000..113e61f
--- /dev/null
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Nem áll rendelkezésre"</item>
+ <item msgid="3048856902433862868">"Ki"</item>
+ <item msgid="6877982264300789870">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Nem áll rendelkezésre"</item>
+ <item msgid="4293012229142257455">"Ki"</item>
+ <item msgid="6221288736127914861">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Nem áll rendelkezésre"</item>
+ <item msgid="2074416252859094119">"Ki"</item>
+ <item msgid="287997784730044767">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Nem áll rendelkezésre"</item>
+ <item msgid="7838121007534579872">"Ki"</item>
+ <item msgid="1578872232501319194">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Nem áll rendelkezésre"</item>
+ <item msgid="5376619709702103243">"Ki"</item>
+ <item msgid="4875147066469902392">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Nem áll rendelkezésre"</item>
+ <item msgid="5044688398303285224">"Ki"</item>
+ <item msgid="8527389108867454098">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Nem áll rendelkezésre"</item>
+ <item msgid="5776427577477729185">"Ki"</item>
+ <item msgid="7105052717007227415">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Nem áll rendelkezésre"</item>
+ <item msgid="5315121904534729843">"Ki"</item>
+ <item msgid="503679232285959074">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Nem áll rendelkezésre"</item>
+ <item msgid="4801037224991420996">"Ki"</item>
+ <item msgid="1982293347302546665">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Nem áll rendelkezésre"</item>
+ <item msgid="4813655083852587017">"Ki"</item>
+ <item msgid="6744077414775180687">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Nem áll rendelkezésre"</item>
+ <item msgid="5715725170633593906">"Ki"</item>
+ <item msgid="2075645297847971154">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Nem áll rendelkezésre"</item>
+ <item msgid="9103697205127645916">"Ki"</item>
+ <item msgid="8067744885820618230">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Nem áll rendelkezésre"</item>
+ <item msgid="6983679487661600728">"Ki"</item>
+ <item msgid="7520663805910678476">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Nem áll rendelkezésre"</item>
+ <item msgid="400477985171353">"Ki"</item>
+ <item msgid="630890598801118771">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Nem áll rendelkezésre"</item>
+ <item msgid="8045580926543311193">"Ki"</item>
+ <item msgid="4913460972266982499">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Nem áll rendelkezésre"</item>
+ <item msgid="1488620600954313499">"Ki"</item>
+ <item msgid="588467578853244035">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Nem áll rendelkezésre"</item>
+ <item msgid="2744885441164350155">"Ki"</item>
+ <item msgid="151121227514952197">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Nem áll rendelkezésre"</item>
+ <item msgid="8259411607272330225">"Ki"</item>
+ <item msgid="578444932039713369">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Nem áll rendelkezésre"</item>
+ <item msgid="8707481475312432575">"Ki"</item>
+ <item msgid="8031106212477483874">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Nem áll rendelkezésre"</item>
+ <item msgid="4572245614982283078">"Ki"</item>
+ <item msgid="6536448410252185664">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Nem áll rendelkezésre"</item>
+ <item msgid="4765607635752003190">"Ki"</item>
+ <item msgid="1697460731949649844">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Nem áll rendelkezésre"</item>
+ <item msgid="3296179158646568218">"Ki"</item>
+ <item msgid="8998632451221157987">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Nem áll rendelkezésre"</item>
+ <item msgid="4544919905196727508">"Ki"</item>
+ <item msgid="3422023746567004609">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Nem áll rendelkezésre"</item>
+ <item msgid="7571394439974244289">"Ki"</item>
+ <item msgid="6866424167599381915">"Be"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Nem áll rendelkezésre"</item>
+ <item msgid="2710157085538036590">"Ki"</item>
+ <item msgid="7809470840976856149">"Be"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
new file mode 100644
index 0000000..d142069
--- /dev/null
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Elemento non disponibile"</item>
+ <item msgid="3048856902433862868">"Off"</item>
+ <item msgid="6877982264300789870">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Elemento non disponibile"</item>
+ <item msgid="4293012229142257455">"Off"</item>
+ <item msgid="6221288736127914861">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Elemento non disponibile"</item>
+ <item msgid="2074416252859094119">"Off"</item>
+ <item msgid="287997784730044767">"On"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Elemento non disponibile"</item>
+ <item msgid="7838121007534579872">"Off"</item>
+ <item msgid="1578872232501319194">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Elemento non disponibile"</item>
+ <item msgid="5376619709702103243">"Off"</item>
+ <item msgid="4875147066469902392">"On"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Elemento non disponibile"</item>
+ <item msgid="5044688398303285224">"Off"</item>
+ <item msgid="8527389108867454098">"On"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Elemento non disponibile"</item>
+ <item msgid="5776427577477729185">"Off"</item>
+ <item msgid="7105052717007227415">"On"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Elemento non disponibile"</item>
+ <item msgid="5315121904534729843">"Off"</item>
+ <item msgid="503679232285959074">"On"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Elemento non disponibile"</item>
+ <item msgid="4801037224991420996">"Off"</item>
+ <item msgid="1982293347302546665">"On"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Elemento non disponibile"</item>
+ <item msgid="4813655083852587017">"Off"</item>
+ <item msgid="6744077414775180687">"On"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Elemento non disponibile"</item>
+ <item msgid="5715725170633593906">"Off"</item>
+ <item msgid="2075645297847971154">"On"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Elemento non disponibile"</item>
+ <item msgid="9103697205127645916">"Off"</item>
+ <item msgid="8067744885820618230">"On"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Elemento non disponibile"</item>
+ <item msgid="6983679487661600728">"Off"</item>
+ <item msgid="7520663805910678476">"On"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Elemento non disponibile"</item>
+ <item msgid="400477985171353">"Off"</item>
+ <item msgid="630890598801118771">"On"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Elemento non disponibile"</item>
+ <item msgid="8045580926543311193">"Off"</item>
+ <item msgid="4913460972266982499">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Elemento non disponibile"</item>
+ <item msgid="1488620600954313499">"Off"</item>
+ <item msgid="588467578853244035">"On"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Elemento non disponibile"</item>
+ <item msgid="2744885441164350155">"Off"</item>
+ <item msgid="151121227514952197">"On"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Elemento non disponibile"</item>
+ <item msgid="8259411607272330225">"Off"</item>
+ <item msgid="578444932039713369">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Elemento non disponibile"</item>
+ <item msgid="8707481475312432575">"Off"</item>
+ <item msgid="8031106212477483874">"On"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Elemento non disponibile"</item>
+ <item msgid="4572245614982283078">"Off"</item>
+ <item msgid="6536448410252185664">"On"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Elemento non disponibile"</item>
+ <item msgid="4765607635752003190">"Off"</item>
+ <item msgid="1697460731949649844">"On"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Elemento non disponibile"</item>
+ <item msgid="3296179158646568218">"Off"</item>
+ <item msgid="8998632451221157987">"On"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Elemento non disponibile"</item>
+ <item msgid="4544919905196727508">"Off"</item>
+ <item msgid="3422023746567004609">"On"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Elemento non disponibile"</item>
+ <item msgid="7571394439974244289">"Off"</item>
+ <item msgid="6866424167599381915">"On"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Elemento non disponibile"</item>
+ <item msgid="2710157085538036590">"Off"</item>
+ <item msgid="7809470840976856149">"On"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 9df9db6..34bf28a 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -64,4 +64,6 @@
<!-- (footer_height -48dp)/2 -->
<dimen name="controls_management_footer_top_margin">4dp</dimen>
<dimen name="controls_management_favorites_top_margin">8dp</dimen>
+
+ <dimen name="wallet_card_carousel_container_top_margin">24dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
new file mode 100644
index 0000000..ac5da6f
--- /dev/null
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="3048856902433862868">"ປິດ"</item>
+ <item msgid="6877982264300789870">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4293012229142257455">"ປິດ"</item>
+ <item msgid="6221288736127914861">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="2074416252859094119">"ປິດ"</item>
+ <item msgid="287997784730044767">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="7838121007534579872">"ປິດ"</item>
+ <item msgid="1578872232501319194">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="5376619709702103243">"ປິດ"</item>
+ <item msgid="4875147066469902392">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="5044688398303285224">"ປິດ"</item>
+ <item msgid="8527389108867454098">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="5776427577477729185">"ປິດ"</item>
+ <item msgid="7105052717007227415">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="5315121904534729843">"ປິດ"</item>
+ <item msgid="503679232285959074">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4801037224991420996">"ປິດ"</item>
+ <item msgid="1982293347302546665">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4813655083852587017">"ປິດ"</item>
+ <item msgid="6744077414775180687">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="5715725170633593906">"ປິດ"</item>
+ <item msgid="2075645297847971154">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="9103697205127645916">"ປິດ"</item>
+ <item msgid="8067744885820618230">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="6983679487661600728">"ປິດ"</item>
+ <item msgid="7520663805910678476">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="400477985171353">"ປິດ"</item>
+ <item msgid="630890598801118771">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="8045580926543311193">"ປິດ"</item>
+ <item msgid="4913460972266982499">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="1488620600954313499">"ປິດ"</item>
+ <item msgid="588467578853244035">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="2744885441164350155">"ປິດ"</item>
+ <item msgid="151121227514952197">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="8259411607272330225">"ປິດ"</item>
+ <item msgid="578444932039713369">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="8707481475312432575">"ປິດ"</item>
+ <item msgid="8031106212477483874">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4572245614982283078">"ປິດ"</item>
+ <item msgid="6536448410252185664">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4765607635752003190">"ປິດ"</item>
+ <item msgid="1697460731949649844">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="3296179158646568218">"ປິດ"</item>
+ <item msgid="8998632451221157987">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="4544919905196727508">"ປິດ"</item>
+ <item msgid="3422023746567004609">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="7571394439974244289">"ປິດ"</item>
+ <item msgid="6866424167599381915">"ເປີດ"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="2710157085538036590">"ປິດ"</item>
+ <item msgid="7809470840976856149">"ເປີດ"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
new file mode 100644
index 0000000..06b1048
--- /dev/null
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Niet beschikbaar"</item>
+ <item msgid="3048856902433862868">"Uit"</item>
+ <item msgid="6877982264300789870">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Niet beschikbaar"</item>
+ <item msgid="4293012229142257455">"Uit"</item>
+ <item msgid="6221288736127914861">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Niet beschikbaar"</item>
+ <item msgid="2074416252859094119">"Uit"</item>
+ <item msgid="287997784730044767">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Niet beschikbaar"</item>
+ <item msgid="7838121007534579872">"Uit"</item>
+ <item msgid="1578872232501319194">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Niet beschikbaar"</item>
+ <item msgid="5376619709702103243">"Uit"</item>
+ <item msgid="4875147066469902392">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Niet beschikbaar"</item>
+ <item msgid="5044688398303285224">"Uit"</item>
+ <item msgid="8527389108867454098">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Niet beschikbaar"</item>
+ <item msgid="5776427577477729185">"Uit"</item>
+ <item msgid="7105052717007227415">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Niet beschikbaar"</item>
+ <item msgid="5315121904534729843">"Uit"</item>
+ <item msgid="503679232285959074">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Niet beschikbaar"</item>
+ <item msgid="4801037224991420996">"Uit"</item>
+ <item msgid="1982293347302546665">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Niet beschikbaar"</item>
+ <item msgid="4813655083852587017">"Uit"</item>
+ <item msgid="6744077414775180687">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Niet beschikbaar"</item>
+ <item msgid="5715725170633593906">"Uit"</item>
+ <item msgid="2075645297847971154">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Niet beschikbaar"</item>
+ <item msgid="9103697205127645916">"Uit"</item>
+ <item msgid="8067744885820618230">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Niet beschikbaar"</item>
+ <item msgid="6983679487661600728">"Uit"</item>
+ <item msgid="7520663805910678476">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Niet beschikbaar"</item>
+ <item msgid="400477985171353">"Uit"</item>
+ <item msgid="630890598801118771">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Niet beschikbaar"</item>
+ <item msgid="8045580926543311193">"Uit"</item>
+ <item msgid="4913460972266982499">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Niet beschikbaar"</item>
+ <item msgid="1488620600954313499">"Uit"</item>
+ <item msgid="588467578853244035">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Niet beschikbaar"</item>
+ <item msgid="2744885441164350155">"Uit"</item>
+ <item msgid="151121227514952197">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Niet beschikbaar"</item>
+ <item msgid="8259411607272330225">"Uit"</item>
+ <item msgid="578444932039713369">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Niet beschikbaar"</item>
+ <item msgid="8707481475312432575">"Uit"</item>
+ <item msgid="8031106212477483874">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Niet beschikbaar"</item>
+ <item msgid="4572245614982283078">"Uit"</item>
+ <item msgid="6536448410252185664">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Niet beschikbaar"</item>
+ <item msgid="4765607635752003190">"Uit"</item>
+ <item msgid="1697460731949649844">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Niet beschikbaar"</item>
+ <item msgid="3296179158646568218">"Uit"</item>
+ <item msgid="8998632451221157987">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Niet beschikbaar"</item>
+ <item msgid="4544919905196727508">"Uit"</item>
+ <item msgid="3422023746567004609">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Niet beschikbaar"</item>
+ <item msgid="7571394439974244289">"Uit"</item>
+ <item msgid="6866424167599381915">"Aan"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Niet beschikbaar"</item>
+ <item msgid="2710157085538036590">"Uit"</item>
+ <item msgid="7809470840976856149">"Aan"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
new file mode 100644
index 0000000..1b213b3
--- /dev/null
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Niedostępny"</item>
+ <item msgid="3048856902433862868">"Wyłączony"</item>
+ <item msgid="6877982264300789870">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Niedostępny"</item>
+ <item msgid="4293012229142257455">"Wyłączony"</item>
+ <item msgid="6221288736127914861">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Niedostępny"</item>
+ <item msgid="2074416252859094119">"Wyłączony"</item>
+ <item msgid="287997784730044767">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Niedostępny"</item>
+ <item msgid="7838121007534579872">"Wyłączony"</item>
+ <item msgid="1578872232501319194">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Niedostępny"</item>
+ <item msgid="5376619709702103243">"Wyłączony"</item>
+ <item msgid="4875147066469902392">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Niedostępny"</item>
+ <item msgid="5044688398303285224">"Wyłączony"</item>
+ <item msgid="8527389108867454098">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Niedostępny"</item>
+ <item msgid="5776427577477729185">"Wyłączony"</item>
+ <item msgid="7105052717007227415">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Niedostępny"</item>
+ <item msgid="5315121904534729843">"Wyłączony"</item>
+ <item msgid="503679232285959074">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Niedostępny"</item>
+ <item msgid="4801037224991420996">"Wyłączony"</item>
+ <item msgid="1982293347302546665">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Niedostępny"</item>
+ <item msgid="4813655083852587017">"Wyłączony"</item>
+ <item msgid="6744077414775180687">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Niedostępny"</item>
+ <item msgid="5715725170633593906">"Wyłączony"</item>
+ <item msgid="2075645297847971154">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Niedostępny"</item>
+ <item msgid="9103697205127645916">"Wyłączony"</item>
+ <item msgid="8067744885820618230">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Niedostępny"</item>
+ <item msgid="6983679487661600728">"Wyłączony"</item>
+ <item msgid="7520663805910678476">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Niedostępny"</item>
+ <item msgid="400477985171353">"Wyłączony"</item>
+ <item msgid="630890598801118771">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Niedostępny"</item>
+ <item msgid="8045580926543311193">"Wyłączony"</item>
+ <item msgid="4913460972266982499">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Niedostępny"</item>
+ <item msgid="1488620600954313499">"Wyłączony"</item>
+ <item msgid="588467578853244035">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Niedostępny"</item>
+ <item msgid="2744885441164350155">"Wyłączony"</item>
+ <item msgid="151121227514952197">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Niedostępny"</item>
+ <item msgid="8259411607272330225">"Wyłączony"</item>
+ <item msgid="578444932039713369">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Niedostępny"</item>
+ <item msgid="8707481475312432575">"Wyłączony"</item>
+ <item msgid="8031106212477483874">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Niedostępny"</item>
+ <item msgid="4572245614982283078">"Wyłączony"</item>
+ <item msgid="6536448410252185664">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Niedostępny"</item>
+ <item msgid="4765607635752003190">"Wyłączony"</item>
+ <item msgid="1697460731949649844">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Niedostępny"</item>
+ <item msgid="3296179158646568218">"Wyłączony"</item>
+ <item msgid="8998632451221157987">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Niedostępny"</item>
+ <item msgid="4544919905196727508">"Wyłączony"</item>
+ <item msgid="3422023746567004609">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Niedostępny"</item>
+ <item msgid="7571394439974244289">"Wyłączony"</item>
+ <item msgid="6866424167599381915">"Włączony"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Niedostępny"</item>
+ <item msgid="2710157085538036590">"Wyłączony"</item>
+ <item msgid="7809470840976856149">"Włączony"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
new file mode 100644
index 0000000..5801d30
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Indisponível"</item>
+ <item msgid="3048856902433862868">"Desativada"</item>
+ <item msgid="6877982264300789870">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Indisponível"</item>
+ <item msgid="4293012229142257455">"Desativado"</item>
+ <item msgid="6221288736127914861">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Indisponível"</item>
+ <item msgid="2074416252859094119">"Desativado"</item>
+ <item msgid="287997784730044767">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Indisponível"</item>
+ <item msgid="7838121007534579872">"Desativada"</item>
+ <item msgid="1578872232501319194">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Indisponível"</item>
+ <item msgid="5376619709702103243">"Desativado"</item>
+ <item msgid="4875147066469902392">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Indisponível"</item>
+ <item msgid="5044688398303285224">"Desativada"</item>
+ <item msgid="8527389108867454098">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Indisponível"</item>
+ <item msgid="5776427577477729185">"Desativado"</item>
+ <item msgid="7105052717007227415">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Indisponível"</item>
+ <item msgid="5315121904534729843">"Desativado"</item>
+ <item msgid="503679232285959074">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Indisponível"</item>
+ <item msgid="4801037224991420996">"Desativado"</item>
+ <item msgid="1982293347302546665">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Indisponível"</item>
+ <item msgid="4813655083852587017">"Desativada"</item>
+ <item msgid="6744077414775180687">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Indisponível"</item>
+ <item msgid="5715725170633593906">"Desativado"</item>
+ <item msgid="2075645297847971154">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Indisponível"</item>
+ <item msgid="9103697205127645916">"Desativada"</item>
+ <item msgid="8067744885820618230">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Indisponível"</item>
+ <item msgid="6983679487661600728">"Desativada"</item>
+ <item msgid="7520663805910678476">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Indisponível"</item>
+ <item msgid="400477985171353">"Desativado"</item>
+ <item msgid="630890598801118771">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Indisponível"</item>
+ <item msgid="8045580926543311193">"Desativado"</item>
+ <item msgid="4913460972266982499">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Indisponível"</item>
+ <item msgid="1488620600954313499">"Desativada"</item>
+ <item msgid="588467578853244035">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Indisponível"</item>
+ <item msgid="2744885441164350155">"Desativado"</item>
+ <item msgid="151121227514952197">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Indisponível"</item>
+ <item msgid="8259411607272330225">"Desativada"</item>
+ <item msgid="578444932039713369">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Indisponível"</item>
+ <item msgid="8707481475312432575">"Desativado"</item>
+ <item msgid="8031106212477483874">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Indisponível"</item>
+ <item msgid="4572245614982283078">"Desativado"</item>
+ <item msgid="6536448410252185664">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Indisponível"</item>
+ <item msgid="4765607635752003190">"Desativada"</item>
+ <item msgid="1697460731949649844">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Indisponível"</item>
+ <item msgid="3296179158646568218">"Desativado"</item>
+ <item msgid="8998632451221157987">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Indisponível"</item>
+ <item msgid="4544919905196727508">"Desativada"</item>
+ <item msgid="3422023746567004609">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Indisponível"</item>
+ <item msgid="7571394439974244289">"Desativado"</item>
+ <item msgid="6866424167599381915">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Indisponível"</item>
+ <item msgid="2710157085538036590">"Desativado"</item>
+ <item msgid="7809470840976856149">"Ativado"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
new file mode 100644
index 0000000..9ee9fc2
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Indisponível"</item>
+ <item msgid="3048856902433862868">"Desligado"</item>
+ <item msgid="6877982264300789870">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Indisponível"</item>
+ <item msgid="4293012229142257455">"Desligado"</item>
+ <item msgid="6221288736127914861">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Indisponível"</item>
+ <item msgid="2074416252859094119">"Desligado"</item>
+ <item msgid="287997784730044767">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Indisponível"</item>
+ <item msgid="7838121007534579872">"Desligado"</item>
+ <item msgid="1578872232501319194">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Indisponível"</item>
+ <item msgid="5376619709702103243">"Desligado"</item>
+ <item msgid="4875147066469902392">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Indisponível"</item>
+ <item msgid="5044688398303285224">"Desligado"</item>
+ <item msgid="8527389108867454098">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Indisponível"</item>
+ <item msgid="5776427577477729185">"Desligado"</item>
+ <item msgid="7105052717007227415">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Indisponível"</item>
+ <item msgid="5315121904534729843">"Desligado"</item>
+ <item msgid="503679232285959074">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Indisponível"</item>
+ <item msgid="4801037224991420996">"Desligado"</item>
+ <item msgid="1982293347302546665">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Indisponível"</item>
+ <item msgid="4813655083852587017">"Desligado"</item>
+ <item msgid="6744077414775180687">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Indisponível"</item>
+ <item msgid="5715725170633593906">"Desligado"</item>
+ <item msgid="2075645297847971154">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Indisponível"</item>
+ <item msgid="9103697205127645916">"Desligado"</item>
+ <item msgid="8067744885820618230">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Indisponível"</item>
+ <item msgid="6983679487661600728">"Desligado"</item>
+ <item msgid="7520663805910678476">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Indisponível"</item>
+ <item msgid="400477985171353">"Desligado"</item>
+ <item msgid="630890598801118771">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Indisponível"</item>
+ <item msgid="8045580926543311193">"Desligado"</item>
+ <item msgid="4913460972266982499">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Indisponível"</item>
+ <item msgid="1488620600954313499">"Desligado"</item>
+ <item msgid="588467578853244035">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Indisponível"</item>
+ <item msgid="2744885441164350155">"Desligado"</item>
+ <item msgid="151121227514952197">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Indisponível"</item>
+ <item msgid="8259411607272330225">"Desligado"</item>
+ <item msgid="578444932039713369">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Indisponível"</item>
+ <item msgid="8707481475312432575">"Desligado"</item>
+ <item msgid="8031106212477483874">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Indisponível"</item>
+ <item msgid="4572245614982283078">"Desligado"</item>
+ <item msgid="6536448410252185664">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Indisponível"</item>
+ <item msgid="4765607635752003190">"Desligado"</item>
+ <item msgid="1697460731949649844">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Indisponível"</item>
+ <item msgid="3296179158646568218">"Desligado"</item>
+ <item msgid="8998632451221157987">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Indisponível"</item>
+ <item msgid="4544919905196727508">"Desligado"</item>
+ <item msgid="3422023746567004609">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Indisponível"</item>
+ <item msgid="7571394439974244289">"Desligado"</item>
+ <item msgid="6866424167599381915">"Ligado"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Indisponível"</item>
+ <item msgid="2710157085538036590">"Desligado"</item>
+ <item msgid="7809470840976856149">"Ligado"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
new file mode 100644
index 0000000..5801d30
--- /dev/null
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"Indisponível"</item>
+ <item msgid="3048856902433862868">"Desativada"</item>
+ <item msgid="6877982264300789870">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"Indisponível"</item>
+ <item msgid="4293012229142257455">"Desativado"</item>
+ <item msgid="6221288736127914861">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"Indisponível"</item>
+ <item msgid="2074416252859094119">"Desativado"</item>
+ <item msgid="287997784730044767">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"Indisponível"</item>
+ <item msgid="7838121007534579872">"Desativada"</item>
+ <item msgid="1578872232501319194">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"Indisponível"</item>
+ <item msgid="5376619709702103243">"Desativado"</item>
+ <item msgid="4875147066469902392">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"Indisponível"</item>
+ <item msgid="5044688398303285224">"Desativada"</item>
+ <item msgid="8527389108867454098">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"Indisponível"</item>
+ <item msgid="5776427577477729185">"Desativado"</item>
+ <item msgid="7105052717007227415">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"Indisponível"</item>
+ <item msgid="5315121904534729843">"Desativado"</item>
+ <item msgid="503679232285959074">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"Indisponível"</item>
+ <item msgid="4801037224991420996">"Desativado"</item>
+ <item msgid="1982293347302546665">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"Indisponível"</item>
+ <item msgid="4813655083852587017">"Desativada"</item>
+ <item msgid="6744077414775180687">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"Indisponível"</item>
+ <item msgid="5715725170633593906">"Desativado"</item>
+ <item msgid="2075645297847971154">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"Indisponível"</item>
+ <item msgid="9103697205127645916">"Desativada"</item>
+ <item msgid="8067744885820618230">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"Indisponível"</item>
+ <item msgid="6983679487661600728">"Desativada"</item>
+ <item msgid="7520663805910678476">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"Indisponível"</item>
+ <item msgid="400477985171353">"Desativado"</item>
+ <item msgid="630890598801118771">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"Indisponível"</item>
+ <item msgid="8045580926543311193">"Desativado"</item>
+ <item msgid="4913460972266982499">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"Indisponível"</item>
+ <item msgid="1488620600954313499">"Desativada"</item>
+ <item msgid="588467578853244035">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"Indisponível"</item>
+ <item msgid="2744885441164350155">"Desativado"</item>
+ <item msgid="151121227514952197">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"Indisponível"</item>
+ <item msgid="8259411607272330225">"Desativada"</item>
+ <item msgid="578444932039713369">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"Indisponível"</item>
+ <item msgid="8707481475312432575">"Desativado"</item>
+ <item msgid="8031106212477483874">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"Indisponível"</item>
+ <item msgid="4572245614982283078">"Desativado"</item>
+ <item msgid="6536448410252185664">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"Indisponível"</item>
+ <item msgid="4765607635752003190">"Desativada"</item>
+ <item msgid="1697460731949649844">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"Indisponível"</item>
+ <item msgid="3296179158646568218">"Desativado"</item>
+ <item msgid="8998632451221157987">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"Indisponível"</item>
+ <item msgid="4544919905196727508">"Desativada"</item>
+ <item msgid="3422023746567004609">"Ativada"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"Indisponível"</item>
+ <item msgid="7571394439974244289">"Desativado"</item>
+ <item msgid="6866424167599381915">"Ativado"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"Indisponível"</item>
+ <item msgid="2710157085538036590">"Desativado"</item>
+ <item msgid="7809470840976856149">"Ativado"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
new file mode 100644
index 0000000..9ca8198
--- /dev/null
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -0,0 +1,159 @@
+<?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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for tile_states_default:0 (4578901299524323311) -->
+ <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
+ <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
+ <string-array name="tile_states_internet">
+ <item msgid="5499482407653291407">"නොමැත"</item>
+ <item msgid="3048856902433862868">"අක්රියයි"</item>
+ <item msgid="6877982264300789870">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_wifi">
+ <item msgid="8054147400538405410">"නොමැත"</item>
+ <item msgid="4293012229142257455">"අක්රියයි"</item>
+ <item msgid="6221288736127914861">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_cell">
+ <item msgid="1235899788959500719">"නොමැත"</item>
+ <item msgid="2074416252859094119">"අක්රියයි"</item>
+ <item msgid="287997784730044767">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_battery">
+ <item msgid="6311253873330062961">"නොමැත"</item>
+ <item msgid="7838121007534579872">"අක්රියයි"</item>
+ <item msgid="1578872232501319194">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_dnd">
+ <item msgid="467587075903158357">"නොමැත"</item>
+ <item msgid="5376619709702103243">"අක්රියයි"</item>
+ <item msgid="4875147066469902392">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_flashlight">
+ <item msgid="3465257127433353857">"නොමැත"</item>
+ <item msgid="5044688398303285224">"අක්රියයි"</item>
+ <item msgid="8527389108867454098">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_rotation">
+ <item msgid="4578491772376121579">"නොමැත"</item>
+ <item msgid="5776427577477729185">"අක්රියයි"</item>
+ <item msgid="7105052717007227415">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_bt">
+ <item msgid="5330252067413512277">"නොමැත"</item>
+ <item msgid="5315121904534729843">"අක්රියයි"</item>
+ <item msgid="503679232285959074">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_airplane">
+ <item msgid="1985366811411407764">"නොමැත"</item>
+ <item msgid="4801037224991420996">"අක්රියයි"</item>
+ <item msgid="1982293347302546665">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_location">
+ <item msgid="3316542218706374405">"නොමැත"</item>
+ <item msgid="4813655083852587017">"අක්රියයි"</item>
+ <item msgid="6744077414775180687">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_hotspot">
+ <item msgid="3145597331197351214">"නොමැත"</item>
+ <item msgid="5715725170633593906">"අක්රියයි"</item>
+ <item msgid="2075645297847971154">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_inversion">
+ <item msgid="3638187931191394628">"නොමැත"</item>
+ <item msgid="9103697205127645916">"අක්රියයි"</item>
+ <item msgid="8067744885820618230">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_saver">
+ <item msgid="39714521631367660">"නොමැත"</item>
+ <item msgid="6983679487661600728">"අක්රියයි"</item>
+ <item msgid="7520663805910678476">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_dark">
+ <item msgid="2762596907080603047">"නොමැත"</item>
+ <item msgid="400477985171353">"අක්රියයි"</item>
+ <item msgid="630890598801118771">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_work">
+ <item msgid="389523503690414094">"නොමැත"</item>
+ <item msgid="8045580926543311193">"අක්රියයි"</item>
+ <item msgid="4913460972266982499">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_cast">
+ <item msgid="6032026038702435350">"නොමැත"</item>
+ <item msgid="1488620600954313499">"අක්රියයි"</item>
+ <item msgid="588467578853244035">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_night">
+ <item msgid="7857498964264855466">"නොමැත"</item>
+ <item msgid="2744885441164350155">"අක්රියයි"</item>
+ <item msgid="151121227514952197">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_screenrecord">
+ <item msgid="1085836626613341403">"නොමැත"</item>
+ <item msgid="8259411607272330225">"අක්රියයි"</item>
+ <item msgid="578444932039713369">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_reverse">
+ <item msgid="3574611556622963971">"නොමැත"</item>
+ <item msgid="8707481475312432575">"අක්රියයි"</item>
+ <item msgid="8031106212477483874">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_reduce_brightness">
+ <item msgid="1839836132729571766">"නොමැත"</item>
+ <item msgid="4572245614982283078">"අක්රියයි"</item>
+ <item msgid="6536448410252185664">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_cameratoggle">
+ <item msgid="6680671247180519913">"නොමැත"</item>
+ <item msgid="4765607635752003190">"අක්රියයි"</item>
+ <item msgid="1697460731949649844">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_mictoggle">
+ <item msgid="6895831614067195493">"නොමැත"</item>
+ <item msgid="3296179158646568218">"අක්රියයි"</item>
+ <item msgid="8998632451221157987">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_controls">
+ <item msgid="8199009425335668294">"නොමැත"</item>
+ <item msgid="4544919905196727508">"අක්රියයි"</item>
+ <item msgid="3422023746567004609">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_wallet">
+ <item msgid="4177615438710836341">"නොමැත"</item>
+ <item msgid="7571394439974244289">"අක්රියයි"</item>
+ <item msgid="6866424167599381915">"සක්රියයි"</item>
+ </string-array>
+ <string-array name="tile_states_alarm">
+ <item msgid="4936533380177298776">"නොමැත"</item>
+ <item msgid="2710157085538036590">"අක්රියයි"</item>
+ <item msgid="7809470840976856149">"සක්රියයි"</item>
+ </string-array>
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a526803..d901015 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -208,7 +208,7 @@
<dimen name="keyguard_indication_y_translation">24dp</dimen>
<!-- The padding on the bottom of the notifications on the keyguard -->
- <dimen name="keyguard_indication_bottom_padding">12sp</dimen>
+ <dimen name="keyguard_indication_bottom_padding">16sp</dimen>
<!-- The padding at start and end of indication text shown on AOD -->
<dimen name="keyguard_indication_text_padding">16dp</dimen>
@@ -743,6 +743,10 @@
<dimen name="keyguard_clock_lock_margin">16dp</dimen>
<!-- The amount to shift the clocks during a small/large transition -->
<dimen name="keyguard_clock_switch_y_shift">10dp</dimen>
+ <!-- When large clock is showing, offset the smartspace by this amount -->
+ <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
+ <!-- With the large clock, move up slightly from the center -->
+ <dimen name="keyguard_large_clock_top_margin">-52dp</dimen>
<!-- Default line spacing multiplier between hours and minutes of the keyguard clock -->
<item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item>
@@ -1453,6 +1457,7 @@
<dimen name="people_space_messages_count_radius">12dp</dimen>
<dimen name="people_space_widget_background_padding">6dp</dimen>
<dimen name="required_width_for_medium">136dp</dimen>
+ <dimen name="required_height_for_medium">80dp</dimen>
<dimen name="required_width_for_large">120dp</dimen>
<dimen name="required_height_for_large">168dp</dimen>
<dimen name="default_width">146dp</dimen>
@@ -1546,6 +1551,7 @@
<dimen name="wallet_screen_header_icon_size">56dp</dimen>
<dimen name="wallet_screen_header_view_size">80dp</dimen>
<dimen name="card_margin">16dp</dimen>
+ <dimen name="wallet_card_carousel_container_top_margin">48dp</dimen>
<dimen name="card_carousel_dot_offset">24dp</dimen>
<dimen name="card_carousel_dot_unselected_radius">2dp</dimen>
<dimen name="card_carousel_dot_selected_radius">3dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e705803..11a2f70 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1660,7 +1660,7 @@
<!-- Label of the button underneath the card carousel prompting user unlock device. [CHAR LIMIT=NONE] -->
<string name="wallet_action_button_label_unlock">Unlock to pay</string>
<!-- Secondary label of the quick access wallet tile if no card. [CHAR LIMIT=NONE] -->
- <string name="wallet_secondary_label_no_card">Not set up</string>
+ <string name="wallet_secondary_label_no_card">Add a card</string>
<!-- Secondary label of the quick access wallet tile if wallet is still updating. [CHAR LIMIT=NONE] -->
<string name="wallet_secondary_label_updating">Updating</string>
<!-- Secondary label of the quick access wallet tile if device locked. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 998b318..42d628a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -82,8 +82,8 @@
final float scale = sourceBounds.width() <= sourceBounds.height()
? (float) destinationBounds.width() / sourceBounds.width()
: (float) destinationBounds.height() / sourceBounds.height();
- final float left = destinationBounds.left - insets.left * scale;
- final float top = destinationBounds.top - insets.top * scale;
+ final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale;
+ final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale;
mTmpTransform.setScale(scale, scale);
final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
index c90833c..2b35bcd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -345,7 +345,7 @@
// Create our own ClassLoader so we can use our own code as the parent.
ClassLoader classLoader = mManager.getClassLoader(info);
Context pluginContext = new PluginContextWrapper(
- mContext.createPackageContext(pkg, 0), classLoader);
+ mContext.createApplicationContext(info, 0), classLoader);
Class<?> pluginClass = Class.forName(cls, true, classLoader);
// TODO: Only create the plugin before version check if we need it for
// legacy version check.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index 7dc537c..6594d5f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -62,16 +62,15 @@
}
private static Bitmap makeThumbnail(TaskSnapshot snapshot) {
- final HardwareBuffer buffer = snapshot.getHardwareBuffer();
Bitmap thumbnail = null;
- try {
+ try (final HardwareBuffer buffer = snapshot.getHardwareBuffer()) {
if (buffer != null) {
thumbnail = Bitmap.wrapHardwareBuffer(buffer, snapshot.getColorSpace());
}
} catch (IllegalArgumentException ex) {
// TODO(b/157562905): Workaround for a crash when we get a snapshot without this state
Log.e("ThumbnailData", "Unexpected snapshot without USAGE_GPU_SAMPLED_IMAGE: "
- + buffer, ex);
+ + snapshot.getHardwareBuffer(), ex);
}
if (thumbnail == null) {
Point taskSize = snapshot.getTaskSize();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index b3a29a3..b5019b4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -292,9 +292,10 @@
}
case ON_TASK_SNAPSHOT_CHANGED: {
Trace.beginSection("onTaskSnapshotChanged");
+ final TaskSnapshot snapshot = (TaskSnapshot) msg.obj;
+ final ThumbnailData thumbnail = new ThumbnailData(snapshot);
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
- mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
- new ThumbnailData((TaskSnapshot) msg.obj));
+ mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1, thumbnail);
}
Trace.endSection();
break;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ef052c4..a5b2509 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -57,6 +57,7 @@
private View mKeyguardStatusArea;
/** Mutually exclusive with mKeyguardStatusArea */
private View mSmartspaceView;
+ private int mSmartspaceTopOffset;
/**
* Maintain state so that a newly connected plugin can be initialized.
@@ -96,6 +97,9 @@
mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_clock_switch_y_shift);
+
+ mSmartspaceTopOffset = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_smartspace_top_offset);
}
/**
@@ -193,7 +197,7 @@
if (indexOfChild(in) == -1) addView(in);
direction = -1;
smartspaceYTranslation = mSmartspaceView == null ? 0
- : mClockFrame.getTop() - mSmartspaceView.getTop();
+ : mClockFrame.getTop() - mSmartspaceView.getTop() + mSmartspaceTopOffset;
} else {
in = mClockFrame;
out = mLargeClockFrame;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index a28d174..781f34bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -189,10 +189,7 @@
.getDimensionPixelSize(R.dimen.below_clock_padding_end);
mSmartspaceView.setPaddingRelative(startPadding, 0, endPadding, 0);
- // ... but above the large clock
- lp = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
- lp.addRule(RelativeLayout.BELOW, mSmartspaceView.getId());
- mLargeClockFrame.setLayoutParams(lp);
+ updateClockLayout();
View nic = mView.findViewById(
R.id.left_aligned_notification_icon_container);
@@ -235,6 +232,18 @@
*/
public void onDensityOrFontScaleChanged() {
mView.onDensityOrFontScaleChanged();
+
+ updateClockLayout();
+ }
+
+ private void updateClockLayout() {
+ if (mSmartspaceController.isEnabled()) {
+ RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT,
+ MATCH_PARENT);
+ lp.topMargin = getContext().getResources().getDimensionPixelSize(
+ R.dimen.keyguard_large_clock_top_margin);
+ mLargeClockFrame.setLayoutParams(lp);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index e891e5b..17818cd 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -39,7 +39,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
@@ -50,8 +49,6 @@
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.Animation;
import android.view.animation.OvershootInterpolator;
import android.view.animation.TranslateAnimation;
@@ -59,8 +56,10 @@
import androidx.annotation.DimenRes;
import androidx.annotation.NonNull;
+import androidx.core.view.AccessibilityDelegateCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.annotations.VisibleForTesting;
@@ -332,54 +331,6 @@
// Do Nothing
}
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- setupAccessibilityActions(info);
- }
-
- @Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
- fadeIn();
-
- final Rect bounds = getAvailableBounds();
- if (action == R.id.action_move_top_left) {
- setShapeType(ShapeType.OVAL);
- snapToLocation(bounds.left, bounds.top);
- return true;
- }
-
- if (action == R.id.action_move_top_right) {
- setShapeType(ShapeType.OVAL);
- snapToLocation(bounds.right, bounds.top);
- return true;
- }
-
- if (action == R.id.action_move_bottom_left) {
- setShapeType(ShapeType.OVAL);
- snapToLocation(bounds.left, bounds.bottom);
- return true;
- }
-
- if (action == R.id.action_move_bottom_right) {
- setShapeType(ShapeType.OVAL);
- snapToLocation(bounds.right, bounds.bottom);
- return true;
- }
-
- if (action == R.id.action_move_to_edge_and_hide) {
- setShapeType(ShapeType.HALF_OVAL);
- return true;
- }
-
- if (action == R.id.action_move_out_edge_and_show) {
- setShapeType(ShapeType.OVAL);
- return true;
- }
-
- return super.performAccessibilityAction(action, arguments);
- }
-
void show() {
if (isShowing()) {
return;
@@ -526,43 +477,6 @@
mUiHandler.postDelayed(() -> mFadeOutAnimator.start(), FADE_EFFECT_DURATION_MS);
}
- private void setupAccessibilityActions(AccessibilityNodeInfo info) {
- final Resources res = mContext.getResources();
- final AccessibilityAction moveTopLeft =
- new AccessibilityAction(R.id.action_move_top_left,
- res.getString(
- R.string.accessibility_floating_button_action_move_top_left));
- info.addAction(moveTopLeft);
-
- final AccessibilityAction moveTopRight =
- new AccessibilityAction(R.id.action_move_top_right,
- res.getString(
- R.string.accessibility_floating_button_action_move_top_right));
- info.addAction(moveTopRight);
-
- final AccessibilityAction moveBottomLeft =
- new AccessibilityAction(R.id.action_move_bottom_left,
- res.getString(
- R.string.accessibility_floating_button_action_move_bottom_left));
- info.addAction(moveBottomLeft);
-
- final AccessibilityAction moveBottomRight =
- new AccessibilityAction(R.id.action_move_bottom_right,
- res.getString(
- R.string.accessibility_floating_button_action_move_bottom_right));
- info.addAction(moveBottomRight);
-
- final int moveEdgeId = mShapeType == ShapeType.OVAL
- ? R.id.action_move_to_edge_and_hide
- : R.id.action_move_out_edge_and_show;
- final int moveEdgeTextResId = mShapeType == ShapeType.OVAL
- ? R.string.accessibility_floating_button_action_move_to_edge_and_hide_to_half
- : R.string.accessibility_floating_button_action_move_out_edge_and_show;
- final AccessibilityAction moveToOrOutEdge =
- new AccessibilityAction(moveEdgeId, res.getString(moveEdgeTextResId));
- info.addAction(moveToOrOutEdge);
- }
-
private boolean onTouched(MotionEvent event) {
final int action = event.getAction();
final int currentX = (int) event.getX();
@@ -685,6 +599,15 @@
mListView.setLayoutManager(layoutManager);
mListView.addOnItemTouchListener(this);
mListView.animate().setInterpolator(new OvershootInterpolator());
+ mListView.setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(mListView) {
+ @NonNull
+ @Override
+ public AccessibilityDelegateCompat getItemDelegate() {
+ return new ItemDelegateCompat(this,
+ AccessibilityFloatingMenuView.this);
+ }
+ });
+
updateListViewWith(mLastConfiguration);
addView(mListView);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompat.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompat.java
new file mode 100644
index 0000000..93b0676
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompat.java
@@ -0,0 +1,141 @@
+/*
+ * 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.accessibility.floatingmenu;
+
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+
+import com.android.systemui.R;
+import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuView.ShapeType;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * An accessibility item delegate for the individual items of the list view
+ * {@link AccessibilityFloatingMenuView}.
+ */
+final class ItemDelegateCompat extends RecyclerViewAccessibilityDelegate.ItemDelegate {
+ private final WeakReference<AccessibilityFloatingMenuView> mMenuViewRef;
+
+ ItemDelegateCompat(@NonNull RecyclerViewAccessibilityDelegate recyclerViewDelegate,
+ AccessibilityFloatingMenuView menuView) {
+ super(recyclerViewDelegate);
+ this.mMenuViewRef = new WeakReference<>(menuView);
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ if (mMenuViewRef.get() == null) {
+ return;
+ }
+ final AccessibilityFloatingMenuView menuView = mMenuViewRef.get();
+
+ final Resources res = menuView.getResources();
+ final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveTopLeft =
+ new AccessibilityNodeInfoCompat.AccessibilityActionCompat(R.id.action_move_top_left,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_top_left));
+ info.addAction(moveTopLeft);
+
+ final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveTopRight =
+ new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
+ R.id.action_move_top_right,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_top_right));
+ info.addAction(moveTopRight);
+
+ final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveBottomLeft =
+ new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
+ R.id.action_move_bottom_left,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_bottom_left));
+ info.addAction(moveBottomLeft);
+
+ final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveBottomRight =
+ new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
+ R.id.action_move_bottom_right,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_bottom_right));
+ info.addAction(moveBottomRight);
+
+ final int moveEdgeId = menuView.isOvalShape()
+ ? R.id.action_move_to_edge_and_hide
+ : R.id.action_move_out_edge_and_show;
+ final int moveEdgeTextResId = menuView.isOvalShape()
+ ? R.string.accessibility_floating_button_action_move_to_edge_and_hide_to_half
+ : R.string.accessibility_floating_button_action_move_out_edge_and_show;
+ final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveToOrOutEdge =
+ new AccessibilityNodeInfoCompat.AccessibilityActionCompat(moveEdgeId,
+ res.getString(moveEdgeTextResId));
+ info.addAction(moveToOrOutEdge);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle args) {
+ if (mMenuViewRef.get() == null) {
+ return super.performAccessibilityAction(host, action, args);
+ }
+ final AccessibilityFloatingMenuView menuView = mMenuViewRef.get();
+
+ menuView.fadeIn();
+
+ final Rect bounds = menuView.getAvailableBounds();
+ if (action == R.id.action_move_top_left) {
+ menuView.setShapeType(ShapeType.OVAL);
+ menuView.snapToLocation(bounds.left, bounds.top);
+ return true;
+ }
+
+ if (action == R.id.action_move_top_right) {
+ menuView.setShapeType(ShapeType.OVAL);
+ menuView.snapToLocation(bounds.right, bounds.top);
+ return true;
+ }
+
+ if (action == R.id.action_move_bottom_left) {
+ menuView.setShapeType(ShapeType.OVAL);
+ menuView.snapToLocation(bounds.left, bounds.bottom);
+ return true;
+ }
+
+ if (action == R.id.action_move_bottom_right) {
+ menuView.setShapeType(ShapeType.OVAL);
+ menuView.snapToLocation(bounds.right, bounds.bottom);
+ return true;
+ }
+
+ if (action == R.id.action_move_to_edge_and_hide) {
+ menuView.setShapeType(ShapeType.HALF_OVAL);
+ return true;
+ }
+
+ if (action == R.id.action_move_out_edge_and_show) {
+ menuView.setShapeType(ShapeType.OVAL);
+ return true;
+ }
+
+ return super.performAccessibilityAction(host, action, args);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index dd73c4f..95ea8100 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -23,11 +23,7 @@
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PointF
-import android.media.AudioAttributes
-import android.os.VibrationEffect
-import android.os.Vibrator
import android.util.AttributeSet
-import android.util.MathUtils
import android.view.View
import android.view.animation.PathInterpolator
import com.android.internal.graphics.ColorUtils
@@ -36,26 +32,25 @@
private const val RIPPLE_ANIMATION_DURATION: Long = 1533
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
-private const val RIPPLE_VIBRATION_PRIMITIVE: Int = VibrationEffect.Composition.PRIMITIVE_LOW_TICK
-private const val RIPPLE_VIBRATION_SIZE: Int = 60
-private const val RIPPLE_VIBRATION_SCALE_START: Float = 0.6f
-private const val RIPPLE_VIBRATION_SCALE_DECAY: Float = -0.1f
/**
* Expanding ripple effect on the transition from biometric authentication success to showing
* launcher.
*/
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
- private val vibrator: Vibrator? = context?.getSystemService(Vibrator::class.java)
private var rippleInProgress: Boolean = false
private val rippleShader = RippleShader()
private val ripplePaint = Paint()
- private val rippleVibrationEffect = createVibrationEffect(vibrator)
- private val rippleVibrationAttrs =
- AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .build()
+ private var radius: Float = 0.0f
+ set(value) {
+ rippleShader.radius = value
+ field = value
+ }
+ private var origin: PointF = PointF()
+ set(value) {
+ rippleShader.origin = value
+ field = value
+ }
init {
rippleShader.color = 0xffffffff.toInt() // default color
@@ -66,8 +61,8 @@
}
fun setSensorLocation(location: PointF) {
- rippleShader.origin = location
- rippleShader.radius = maxOf(location.x, location.y, width - location.x, height - location.y)
+ origin = location
+ radius = maxOf(location.x, location.y, width - location.x, height - location.y)
.toFloat()
}
@@ -141,8 +136,6 @@
}
})
}
- // TODO (b/185124905): custom haptic TBD
- // vibrate()
animatorSet.start()
}
@@ -151,26 +144,11 @@
}
override fun onDraw(canvas: Canvas?) {
- // draw over the entire screen
- canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint)
- }
-
- private fun vibrate() {
- if (rippleVibrationEffect != null) {
- vibrator?.vibrate(rippleVibrationEffect, rippleVibrationAttrs)
- }
- }
-
- private fun createVibrationEffect(vibrator: Vibrator?): VibrationEffect? {
- if (vibrator?.areAllPrimitivesSupported(RIPPLE_VIBRATION_PRIMITIVE) == false) {
- return null
- }
- val composition = VibrationEffect.startComposition()
- for (i in 0 until RIPPLE_VIBRATION_SIZE) {
- val scale =
- RIPPLE_VIBRATION_SCALE_START * MathUtils.exp(RIPPLE_VIBRATION_SCALE_DECAY * i)
- composition.addPrimitive(RIPPLE_VIBRATION_PRIMITIVE, scale, 0 /* delay */)
- }
- return composition.compose()
+ // To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
+ // the active effect area. Values here should be kept in sync with the
+ // animation implementation in the ripple shader.
+ val maskRadius = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
+ (1 - rippleShader.progress)) * radius * 1.5f
+ canvas?.drawCircle(origin.x, origin.y, maskRadius, ripplePaint)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 2d403f6..1f11894 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -74,7 +74,10 @@
return false;
}
- protected void updateAlpha() {
+ /**
+ * @return current alpha
+ */
+ protected int updateAlpha() {
int alpha = calculateAlpha();
getDrawable().setAlpha(alpha);
@@ -84,6 +87,8 @@
} else {
((ViewGroup) getParent()).setVisibility(View.VISIBLE);
}
+
+ return alpha;
}
int calculateAlpha() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index e5bd893..c5a0dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -147,6 +147,7 @@
@Nullable private Runnable mCancelAodTimeoutAction;
private boolean mScreenOn;
private Runnable mAodInterruptRunnable;
+ private boolean mOnFingerDown;
@VisibleForTesting
public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
@@ -662,12 +663,12 @@
private void showUdfpsOverlay(@NonNull ServerRequest request) {
mExecution.assertIsMainThread();
-
final int reason = request.mRequestReason;
if (mView == null) {
try {
Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
+ mOnFingerDown = false;
mView.setSensorProperties(mSensorProps);
mView.setHbmProvider(mHbmProvider);
UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
@@ -826,6 +827,7 @@
Log.w(TAG, "Null view in onFingerDown");
return;
}
+ mOnFingerDown = true;
mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
@@ -843,7 +845,10 @@
Log.w(TAG, "Null view in onFingerUp");
return;
}
- mFingerprintManager.onPointerUp(mSensorProps.sensorId);
+ if (mOnFingerDown) {
+ mFingerprintManager.onPointerUp(mSensorProps.sensorId);
+ }
+ mOnFingerDown = false;
if (mView.isIlluminationRequested()) {
mView.stopIllumination();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
index 7f4d7fe0..2cdf49d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
@@ -43,11 +43,6 @@
}
@Override
- protected void updateAlpha() {
- super.updateAlpha();
- }
-
- @Override
protected void onFinishInflate() {
mFingerprintView = findViewById(R.id.udfps_enroll_animation_fp_view);
mFingerprintView.setImageDrawable(mFingerprintDrawable);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
deleted file mode 100644
index 8894093..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.biometrics;
-
-import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
-
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.util.MathUtils;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.graphics.ColorUtils;
-import com.android.settingslib.Utils;
-import com.android.systemui.R;
-import com.android.systemui.animation.Interpolators;
-import com.android.systemui.doze.DozeReceiver;
-
-/**
- * UDFPS animations that should be shown when authenticating on keyguard.
- */
-public class UdfpsKeyguardDrawable extends UdfpsDrawable implements DozeReceiver {
-
- private static final String TAG = "UdfpsAnimationKeyguard";
- private final int mAmbientDisplayColor;
- static final float DEFAULT_AOD_STROKE_WIDTH = 1f;
-
- @NonNull private final Context mContext;
- private int mLockScreenColor;
-
- // AOD anti-burn-in offsets
- private final int mMaxBurnInOffsetX;
- private final int mMaxBurnInOffsetY;
- private float mInterpolatedDarkAmount;
- private float mBurnInOffsetX;
- private float mBurnInOffsetY;
-
- private final ValueAnimator mHintAnimator = ValueAnimator.ofFloat(
- UdfpsKeyguardDrawable.DEFAULT_STROKE_WIDTH,
- .5f,
- UdfpsKeyguardDrawable.DEFAULT_STROKE_WIDTH);
-
- UdfpsKeyguardDrawable(@NonNull Context context) {
- super(context);
- mContext = context;
-
- mMaxBurnInOffsetX = context.getResources()
- .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
- mMaxBurnInOffsetY = context.getResources()
- .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
-
- mHintAnimator.setDuration(2000);
- mHintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mHintAnimator.addUpdateListener(anim -> setStrokeWidth((float) anim.getAnimatedValue()));
-
- mLockScreenColor = Utils.getColorAttrDefaultColor(mContext,
- R.attr.wallpaperTextColorAccent);
- mAmbientDisplayColor = Color.WHITE;
-
- updateIcon();
- }
-
- private void updateIcon() {
- mBurnInOffsetX = MathUtils.lerp(0f,
- getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
- - mMaxBurnInOffsetX,
- mInterpolatedDarkAmount);
- mBurnInOffsetY = MathUtils.lerp(0f,
- getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
- - mMaxBurnInOffsetY,
- mInterpolatedDarkAmount);
-
- mFingerprintDrawable.setTint(ColorUtils.blendARGB(mLockScreenColor,
- mAmbientDisplayColor, mInterpolatedDarkAmount));
- setStrokeWidth(MathUtils.lerp(DEFAULT_STROKE_WIDTH, DEFAULT_AOD_STROKE_WIDTH,
- mInterpolatedDarkAmount));
- invalidateSelf();
- }
-
- @Override
- public void dozeTimeTick() {
- updateIcon();
- }
-
- @Override
- public void draw(@NonNull Canvas canvas) {
- if (isIlluminationShowing()) {
- return;
- }
- canvas.save();
- canvas.translate(mBurnInOffsetX, mBurnInOffsetY);
- mFingerprintDrawable.draw(canvas);
- canvas.restore();
- }
-
- void animateHint() {
- mHintAnimator.start();
- }
-
- void onDozeAmountChanged(float linear, float eased) {
- mHintAnimator.cancel();
- mInterpolatedDarkAmount = eased;
- updateIcon();
- }
-
- void setLockScreenColor(int color) {
- if (mLockScreenColor == color) return;
- mLockScreenColor = color;
- updateIcon();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 804e2ab..ec96af3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -16,6 +16,9 @@
package com.android.systemui.biometrics;
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -23,7 +26,10 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
+import android.util.MathUtils;
import android.view.View;
import android.widget.ImageView;
@@ -34,12 +40,17 @@
import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.StatusBarState;
+import com.airbnb.lottie.LottieAnimationView;
+import com.airbnb.lottie.LottieProperty;
+import com.airbnb.lottie.model.KeyPath;
/**
* View corresponding with udfps_keyguard_view.xml
*/
public class UdfpsKeyguardView extends UdfpsAnimationView {
- private final UdfpsKeyguardDrawable mFingerprintDrawable;
- private ImageView mFingerprintView;
+ private UdfpsDrawable mFingerprintDrawable; // placeholder
+ private LottieAnimationView mAodFp;
+ private LottieAnimationView mLockScreenFp;
+ private int mUdfpsBouncerColor;
private int mWallpaperTextColor;
private int mStatusBarState;
@@ -52,16 +63,31 @@
private AnimatorSet mAnimatorSet;
private int mAlpha; // 0-255
+ // AOD anti-burn-in offsets
+ private final int mMaxBurnInOffsetX;
+ private final int mMaxBurnInOffsetY;
+ private float mBurnInOffsetX;
+ private float mBurnInOffsetY;
+ private float mBurnInProgress;
+ private float mInterpolatedDarkAmount;
+
+ private ValueAnimator mHintAnimator;
+
public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mFingerprintDrawable = new UdfpsKeyguardDrawable(mContext);
+ mFingerprintDrawable = new UdfpsFpDrawable(context);
+
+ mMaxBurnInOffsetX = context.getResources()
+ .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
+ mMaxBurnInOffsetY = context.getResources()
+ .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mFingerprintView = findViewById(R.id.udfps_keyguard_animation_fp_view);
- mFingerprintView.setForeground(mFingerprintDrawable);
+ mAodFp = findViewById(R.id.udfps_aod_fp);
+ mLockScreenFp = findViewById(R.id.udfps_lockscreen_fp);
mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg);
@@ -69,7 +95,16 @@
R.attr.wallpaperTextColorAccent);
mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
android.R.attr.textColorPrimary);
+
+ // requires call to invalidate to update the color (see #updateColor)
+ mLockScreenFp.addValueCallback(
+ new KeyPath("**"), LottieProperty.COLOR_FILTER,
+ frameInfo -> new PorterDuffColorFilter(getColor(), PorterDuff.Mode.SRC_ATOP)
+ );
mUdfpsRequested = false;
+
+ mHintAnimator = ObjectAnimator.ofFloat(mLockScreenFp, "progress", 1f, 0f, 1f);
+ mHintAnimator.setDuration(4000);
}
@Override
@@ -89,10 +124,27 @@
@Override
public boolean dozeTimeTick() {
- mFingerprintDrawable.dozeTimeTick();
+ updateBurnInOffsets();
return true;
}
+ private void updateBurnInOffsets() {
+ mBurnInOffsetX = MathUtils.lerp(0f,
+ getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
+ - mMaxBurnInOffsetX, mInterpolatedDarkAmount);
+ mBurnInOffsetY = MathUtils.lerp(0f,
+ getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
+ - mMaxBurnInOffsetY, mInterpolatedDarkAmount);
+ mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
+
+ mAodFp.setTranslationX(mBurnInOffsetX);
+ mAodFp.setTranslationY(mBurnInOffsetY);
+ mAodFp.setProgress(mBurnInProgress);
+
+ mLockScreenFp.setTranslationX(mBurnInOffsetX);
+ mLockScreenFp.setTranslationY(mBurnInOffsetY);
+ }
+
void requestUdfps(boolean request, int color) {
if (request) {
mUdfpsRequestedColor = color;
@@ -105,22 +157,31 @@
void setStatusBarState(int statusBarState) {
mStatusBarState = statusBarState;
- updateColor();
}
void updateColor() {
- mFingerprintView.setAlpha(1f);
- mFingerprintDrawable.setLockScreenColor(getColor());
+ mLockScreenFp.invalidate();
}
+ private boolean showingUdfpsBouncer() {
+ return mBgProtection.getVisibility() == View.VISIBLE;
+ }
+
+
private int getColor() {
- if (mUdfpsRequested && mUdfpsRequestedColor != -1) {
+ if (isUdfpsColorRequested()) {
return mUdfpsRequestedColor;
+ } else if (showingUdfpsBouncer()) {
+ return mUdfpsBouncerColor;
} else {
return mWallpaperTextColor;
}
}
+ private boolean isUdfpsColorRequested() {
+ return mUdfpsRequested && mUdfpsRequestedColor != -1;
+ }
+
/**
* @param alpha between 0 and 255
*/
@@ -130,6 +191,13 @@
}
@Override
+ protected int updateAlpha() {
+ int alpha = super.updateAlpha();
+ mLockScreenFp.setImageAlpha(alpha);
+ return alpha;
+ }
+
+ @Override
int calculateAlpha() {
if (mPauseAuth) {
return 0;
@@ -138,18 +206,31 @@
}
void onDozeAmountChanged(float linear, float eased) {
- mFingerprintDrawable.onDozeAmountChanged(linear, eased);
+ mHintAnimator.cancel();
+ mInterpolatedDarkAmount = eased;
+ updateBurnInOffsets();
+ mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
+ mAodFp.setAlpha(mInterpolatedDarkAmount);
+
+ if (linear == 1f) {
+ mLockScreenFp.setVisibility(View.INVISIBLE);
+ } else {
+ mLockScreenFp.setVisibility(View.VISIBLE);
+ }
}
void animateHint() {
- mFingerprintDrawable.animateHint();
+ if (!isShadeLocked() && !mUdfpsRequested && mAlpha == 255
+ && mLockScreenFp.isVisibleToUser()) {
+ mHintAnimator.start();
+ }
}
/**
* Animates in the bg protection circle behind the fp icon to highlight the icon.
*/
void animateUdfpsBouncer(Runnable onEndAnimation) {
- if (mBgProtection.getVisibility() == View.VISIBLE && mBgProtection.getAlpha() == 1f) {
+ if (showingUdfpsBouncer() && mBgProtection.getAlpha() == 1f) {
// already fully highlighted, don't re-animate
return;
}
@@ -157,19 +238,6 @@
if (mAnimatorSet != null) {
mAnimatorSet.cancel();
}
- ValueAnimator fpIconAnim;
- if (isShadeLocked()) {
- // set color and fade in since we weren't showing before
- mFingerprintDrawable.setLockScreenColor(mTextColorPrimary);
- fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 0f, 1f);
- } else {
- // update icon color
- fpIconAnim = new ValueAnimator();
- fpIconAnim.setIntValues(getColor(), mTextColorPrimary);
- fpIconAnim.setEvaluator(new ArgbEvaluator());
- fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
- (Integer) valueAnimator.getAnimatedValue()));
- }
mAnimatorSet = new AnimatorSet();
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -181,11 +249,31 @@
}
});
+ 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(
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 0f, 1f),
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 0f, 1f),
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f),
- fpIconAnim);
+ fpIconColorAnim);
mAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -197,15 +285,11 @@
mAnimatorSet.start();
}
- private boolean isShadeLocked() {
- return mStatusBarState == StatusBarState.SHADE_LOCKED;
- }
-
/**
* Animates out the bg protection circle behind the fp icon to unhighlight the icon.
*/
void animateAwayUdfpsBouncer(@Nullable Runnable onEndAnimation) {
- if (mBgProtection.getVisibility() == View.GONE) {
+ if (!showingUdfpsBouncer()) {
// already hidden
return;
}
@@ -213,17 +297,25 @@
if (mAnimatorSet != null) {
mAnimatorSet.cancel();
}
- ValueAnimator fpIconAnim;
+
+ ValueAnimator fpIconColorAnim;
if (isShadeLocked()) {
// fade out
- fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 1f, 0f);
+ mUdfpsBouncerColor = mTextColorPrimary;
+ fpIconColorAnim = ValueAnimator.ofInt(255, 0);
+ fpIconColorAnim.addUpdateListener(valueAnimator ->
+ mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue()));
} else {
// update icon color
- fpIconAnim = new ValueAnimator();
- fpIconAnim.setIntValues(mTextColorPrimary, getColor());
- fpIconAnim.setEvaluator(new ArgbEvaluator());
- fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
- (Integer) valueAnimator.getAnimatedValue()));
+ fpIconColorAnim = new ValueAnimator();
+ fpIconColorAnim.setIntValues(
+ mTextColorPrimary,
+ isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor);
+ fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance());
+ fpIconColorAnim.addUpdateListener(valueAnimator -> {
+ mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue();
+ updateColor();
+ });
}
mAnimatorSet = new AnimatorSet();
@@ -231,7 +323,7 @@
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 1f, 0f),
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 1f, 0f),
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 1f, 0f),
- fpIconAnim);
+ fpIconColorAnim);
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mAnimatorSet.setDuration(500);
@@ -244,10 +336,15 @@
}
}
});
+
mAnimatorSet.start();
}
boolean isAnimating() {
return mAnimatorSet != null && mAnimatorSet.isRunning();
}
+
+ private boolean isShadeLocked() {
+ return mStatusBarState == StatusBarState.SHADE_LOCKED;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 35ca470..819de53 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -316,6 +316,14 @@
}
}
+ public void onBiometricError(int msgId, String errString,
+ BiometricSourceType biometricSourceType) {
+ if (biometricSourceType == BiometricSourceType.FACE) {
+ // show udfps hint when face auth fails
+ showHint(true);
+ }
+ }
+
public void onBiometricAuthenticated(int userId,
BiometricSourceType biometricSourceType, boolean isStrongBiometric) {
if (biometricSourceType == BiometricSourceType.FACE) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 020401e..809e7a7 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -25,6 +25,7 @@
import android.os.Build;
import android.util.IndentingPrintWriter;
import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
@@ -70,6 +71,7 @@
private final DoubleTapClassifier mDoubleTapClassifier;
private final HistoryTracker mHistoryTracker;
private final KeyguardStateController mKeyguardStateController;
+ private AccessibilityManager mAccessibilityManager;
private final boolean mTestHarness;
private final MetricsLogger mMetricsLogger;
private int mIsFalseTouchCalls;
@@ -175,6 +177,7 @@
@Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier,
HistoryTracker historyTracker, KeyguardStateController keyguardStateController,
+ AccessibilityManager accessibilityManager,
@TestHarness boolean testHarness) {
mDataProvider = falsingDataProvider;
mDockManager = dockManager;
@@ -184,6 +187,7 @@
mDoubleTapClassifier = doubleTapClassifier;
mHistoryTracker = historyTracker;
mKeyguardStateController = keyguardStateController;
+ mAccessibilityManager = accessibilityManager;
mTestHarness = testHarness;
mDataProvider.addSessionListener(mSessionListener);
@@ -328,7 +332,8 @@
|| !mKeyguardStateController.isShowing()
|| mTestHarness
|| mDataProvider.isJustUnlockedWithFace()
- || mDockManager.isDocked();
+ || mDockManager.isDocked()
+ || mAccessibilityManager.isEnabled();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
index 73abf45..15e3f3a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
@@ -22,6 +22,7 @@
private const val BURN_IN_PREVENTION_PERIOD_Y = 521f
private const val BURN_IN_PREVENTION_PERIOD_X = 83f
private const val BURN_IN_PREVENTION_PERIOD_SCALE = 180f
+private const val BURN_IN_PREVENTION_PERIOD_PROGRESS = 120f
/**
* Returns the translation offset that should be used to avoid burn in at
@@ -37,6 +38,15 @@
}
/**
+ * Returns a progress offset (between 0f and 1.0f) that should be used to avoid burn in at
+ * the current time.
+ */
+fun getBurnInProgressOffset(): Float {
+ return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+ 1f, BURN_IN_PREVENTION_PERIOD_PROGRESS)
+}
+
+/**
* Returns a value to scale a view in order to avoid burn in.
*/
fun getBurnInScale(): Float {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index df9977f..2d215e0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -23,7 +23,6 @@
import androidx.annotation.IntDef;
-import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -164,17 +163,14 @@
* Transient messages:
* - show immediately
* - will continue to be in the rotation of messages shown until hideTransient is called.
- * - can be presented with an "error" color if isError is true
*/
- public void showTransient(CharSequence newIndication, boolean isError) {
+ public void showTransient(CharSequence newIndication) {
final long inAnimationDuration = 600L; // see KeyguardIndicationTextView.getYInDuration
updateIndication(INDICATION_TYPE_TRANSIENT,
new KeyguardIndication.Builder()
.setMessage(newIndication)
- .setTextColor(isError
- ? Utils.getColorError(getContext())
- : mInitialTextColorState)
.setMinVisibilityMillis(2000L + inAnimationDuration)
+ .setTextColor(mInitialTextColorState)
.build(),
/* showImmediately */true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 8c6a3ca..cc9414c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -26,6 +26,7 @@
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.animation.requiresRemeasuring
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import java.util.TreeMap
import javax.inject.Inject
import javax.inject.Provider
@@ -45,6 +46,7 @@
private val visualStabilityManager: VisualStabilityManager,
private val mediaHostStatesManager: MediaHostStatesManager,
private val activityStarter: ActivityStarter,
+ private val systemClock: SystemClock,
@Main executor: DelayableExecutor,
private val mediaManager: MediaDataManager,
configurationController: ConfigurationController,
@@ -358,12 +360,12 @@
newPlayer.playerViewHolder?.player?.setLayoutParams(lp)
newPlayer.bindPlayer(dataCopy, key)
newPlayer.setListening(currentlyExpanded)
- MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer)
+ MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer, systemClock)
updatePlayerToState(newPlayer, noAnimation = true)
reorderAllPlayers(curVisibleMediaKey)
} else {
existingPlayer.bindPlayer(dataCopy, key)
- MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer)
+ MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer, systemClock)
if (visualStabilityManager.isReorderingAllowed || shouldScrollToActivePlayer) {
reorderAllPlayers(curVisibleMediaKey)
} else {
@@ -407,7 +409,7 @@
newRecs.bindRecommendation(data.copy(backgroundColor = bgColor))
val curVisibleMediaKey = MediaPlayerData.playerKeys()
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
- MediaPlayerData.addMediaRecommendation(key, data, newRecs, shouldPrioritize)
+ MediaPlayerData.addMediaRecommendation(key, data, newRecs, shouldPrioritize, systemClock)
updatePlayerToState(newRecs, noAnimation = true)
reorderAllPlayers(curVisibleMediaKey)
updatePageIndicator()
@@ -775,9 +777,9 @@
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
- fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) {
+ fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel, clock: SystemClock) {
removeMediaPlayer(key)
- val sortKey = MediaSortKey(isSsMediaRec = false, data, System.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = false, data, clock.currentTimeMillis())
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
}
@@ -786,11 +788,12 @@
key: String,
data: SmartspaceMediaData,
player: MediaControlPanel,
- shouldPrioritize: Boolean
+ shouldPrioritize: Boolean,
+ clock: SystemClock
) {
shouldPrioritizeSs = shouldPrioritize
removeMediaPlayer(key)
- val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, System.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, clock.currentTimeMillis())
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
smartspaceMediaData = data
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java b/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java
index 452484f..3bc1f30e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java
@@ -58,7 +58,7 @@
public static final int JOB_ID = 74823873;
private static final long JOB_PERIODIC_DURATION = Duration.ofHours(6).toMillis();
- private static final long CLEAN_UP_STORAGE_AFTER_DURATION = Duration.ofHours(24).toMillis();
+ private static final long CLEAN_UP_STORAGE_AFTER_DURATION = Duration.ofHours(48).toMillis();
/** SharedPreferences file name for follow-up specific storage.*/
public static final String SHARED_FOLLOW_UP = "shared_follow_up";
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index dcab86b..c01d6dc 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -75,7 +75,8 @@
/** Utils class for People Space. */
public class PeopleSpaceUtils {
/** Turns on debugging information about People Space. */
- public static final boolean DEBUG = true;
+ public static final boolean DEBUG = false;
+
public static final String PACKAGE_NAME = "package_name";
public static final String USER_ID = "user_id";
public static final String SHORTCUT_ID = "shortcut_id";
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index d363614..8194adcd 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -97,7 +97,7 @@
/** Functions that help creating the People tile layouts. */
public class PeopleTileViewHelper {
/** Turns on debugging information about People Space. */
- public static final boolean DEBUG = true;
+ private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private static final String TAG = "PeopleTileView";
private static final int DAYS_IN_A_WEEK = 7;
@@ -116,8 +116,10 @@
private static final int MIN_MEDIUM_VERTICAL_PADDING = 4;
private static final int MAX_MEDIUM_PADDING = 16;
private static final int FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT_BEFORE_PADDING = 8 + 4;
- private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL = 6 + 4 + 8;
- private static final int FIXED_WIDTH_DIMENS_FOR_SMALL = 4 + 4;
+ private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL_VERTICAL = 6 + 4 + 8;
+ private static final int FIXED_WIDTH_DIMENS_FOR_SMALL_VERTICAL = 4 + 4;
+ private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL_HORIZONTAL = 6 + 4;
+ private static final int FIXED_WIDTH_DIMENS_FOR_SMALL_HORIZONTAL = 8 + 8;
private static final int MESSAGES_COUNT_OVERFLOW = 6;
@@ -220,7 +222,7 @@
// Otherwise, create a list using the portrait/landscape sizes.
int defaultWidth = getSizeInDp(context, R.dimen.default_width, density);
- int defaultHeight = getSizeInDp(context, R.dimen.default_height, density);
+ int defaultHeight = getSizeInDp(context, R.dimen.default_height, density);
widgetSizes = new ArrayList<>(2);
int portraitWidth = options.getInt(OPTION_APPWIDGET_MIN_WIDTH, defaultWidth);
@@ -404,7 +406,8 @@
return LAYOUT_LARGE;
}
// Small layout used below a certain minimum mWidth with any mHeight.
- if (mWidth >= getSizeInDp(R.dimen.required_width_for_medium)) {
+ if (mHeight >= getSizeInDp(R.dimen.required_height_for_medium)
+ && mWidth >= getSizeInDp(R.dimen.required_width_for_medium)) {
int spaceAvailableForPadding =
mHeight - (getSizeInDp(R.dimen.avatar_size_for_medium)
+ 4 + getLineHeightFromResource(
@@ -437,10 +440,15 @@
// Calculate adaptive avatar size for remaining layouts.
if (layoutId == R.layout.people_tile_small) {
- int avatarHeightSpace = mHeight - (FIXED_HEIGHT_DIMENS_FOR_SMALL + Math.max(18,
+ int avatarHeightSpace = mHeight - (FIXED_HEIGHT_DIMENS_FOR_SMALL_VERTICAL + Math.max(18,
getLineHeightFromResource(
R.dimen.name_text_size_for_small)));
- int avatarWidthSpace = mWidth - FIXED_WIDTH_DIMENS_FOR_SMALL;
+ int avatarWidthSpace = mWidth - FIXED_WIDTH_DIMENS_FOR_SMALL_VERTICAL;
+ avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace);
+ }
+ if (layoutId == R.layout.people_tile_small_horizontal) {
+ int avatarHeightSpace = mHeight - FIXED_HEIGHT_DIMENS_FOR_SMALL_HORIZONTAL;
+ int avatarWidthSpace = mWidth - FIXED_WIDTH_DIMENS_FOR_SMALL_HORIZONTAL;
avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace);
}
@@ -1033,7 +1041,7 @@
return R.layout.people_tile_large_empty;
case LAYOUT_SMALL:
default:
- return R.layout.people_tile_small;
+ return getLayoutSmallByHeight();
}
}
@@ -1045,7 +1053,7 @@
return R.layout.people_tile_large_with_notification_content;
case LAYOUT_SMALL:
default:
- return R.layout.people_tile_small;
+ return getLayoutSmallByHeight();
}
}
@@ -1057,10 +1065,17 @@
return R.layout.people_tile_large_with_status_content;
case LAYOUT_SMALL:
default:
- return R.layout.people_tile_small;
+ return getLayoutSmallByHeight();
}
}
+ private int getLayoutSmallByHeight() {
+ if (mHeight >= getSizeInDp(R.dimen.required_height_for_medium)) {
+ return R.layout.people_tile_small;
+ }
+ return R.layout.people_tile_small_horizontal;
+ }
+
/** Returns a bitmap with the user icon and package icon. */
public static Bitmap getPersonIconBitmap(
Context context, PeopleSpaceTile tile, int maxAvatarSize) {
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 72cddd0..3320fbd 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -106,6 +106,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -398,7 +399,7 @@
ConversationChannel channel = mIPeopleManager.getConversation(
key.getPackageName(), key.getUserId(), key.getShortcutId());
if (channel == null) {
- Log.d(TAG, "Could not retrieve conversation from storage");
+ if (DEBUG) Log.d(TAG, "Could not retrieve conversation from storage");
return null;
}
@@ -585,7 +586,7 @@
@Nullable
public Optional<PeopleSpaceTile> getAugmentedTileForExistingWidget(int widgetId,
Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
- Log.d(TAG, "Augmenting tile for existing widget: " + widgetId);
+ if (DEBUG) Log.d(TAG, "Augmenting tile for existing widget: " + widgetId);
PeopleSpaceTile tile = getTileForExistingWidget(widgetId);
if (tile == null) {
if (DEBUG) {
@@ -1246,9 +1247,13 @@
/** Remaps widget ids in widget specific files. */
public void remapWidgetFiles(Map<String, String> widgets) {
if (DEBUG) Log.d(TAG, "Remapping widget files");
+ Map<String, PeopleTileKey> remapped = new HashMap<>();
for (Map.Entry<String, String> entry : widgets.entrySet()) {
String from = String.valueOf(entry.getKey());
String to = String.valueOf(entry.getValue());
+ if (Objects.equals(from, to)) {
+ continue;
+ }
SharedPreferences src = mContext.getSharedPreferences(from, Context.MODE_PRIVATE);
PeopleTileKey key = SharedPreferencesHelper.getPeopleTileKey(src);
@@ -1257,11 +1262,17 @@
Log.d(TAG, "Moving PeopleTileKey: " + key.toString() + " from file: "
+ from + ", to file: " + to);
}
- SharedPreferences dest = mContext.getSharedPreferences(to, Context.MODE_PRIVATE);
- SharedPreferencesHelper.setPeopleTileKey(dest, key);
+ remapped.put(to, key);
SharedPreferencesHelper.clear(src);
+ } else {
+ if (DEBUG) Log.d(TAG, "Widget file has invalid key: " + key);
}
}
+ for (Map.Entry<String, PeopleTileKey> entry : remapped.entrySet()) {
+ SharedPreferences dest = mContext.getSharedPreferences(
+ entry.getKey(), Context.MODE_PRIVATE);
+ SharedPreferencesHelper.setPeopleTileKey(dest, entry.getValue());
+ }
}
/** Remaps widget ids in default shared storage. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 74550f2..e9b19e5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -215,7 +215,7 @@
public void setExpansion(float expansion) {
mQsExpansion = expansion;
- mQSPanelContainer.setScrollingEnabled(expansion > 0.0f);
+ mQSPanelContainer.setScrollingEnabled(expansion > 0f);
updateExpansion();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 998cff2..0d91f29 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -108,6 +108,7 @@
private QSPanelController mQSPanelController;
private QuickQSPanelController mQuickQSPanelController;
private QSCustomizerController mQSCustomizerController;
+ private ScrollListener mScrollListener;
private FeatureFlags mFeatureFlags;
/**
* When true, QS will translate from outside the screen. It will be clipped with parallax
@@ -171,9 +172,12 @@
});
mQSPanelScrollView.setOnScrollChangeListener(
(v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
- // Lazily update animators whenever the scrolling changes
- mQSAnimator.onQsScrollingChanged();
- mHeader.setExpandedScrollAmount(scrollY);
+ // Lazily update animators whenever the scrolling changes
+ mQSAnimator.onQsScrollingChanged();
+ mHeader.setExpandedScrollAmount(scrollY);
+ if (mScrollListener != null) {
+ mScrollListener.onQsPanelScrollChanged(scrollY);
+ }
});
mQSDetail = view.findViewById(R.id.qs_detail);
mHeader = view.findViewById(R.id.header);
@@ -214,6 +218,11 @@
}
@Override
+ public void setScrollListener(ScrollListener listener) {
+ mScrollListener = listener;
+ }
+
+ @Override
public void onDestroy() {
super.onDestroy();
mStatusBarStateController.removeCallback(this);
@@ -222,6 +231,7 @@
}
mQSCustomizerController.setQs(null);
mQsDetailDisplayer.setQsPanelController(null);
+ mScrollListener = null;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 4dc7508..82b6c0c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -158,7 +158,11 @@
CharSequence label = mController.getWalletClient().getServiceLabel();
state.label = label == null ? mLabel : label;
state.contentDescription = state.label;
- state.icon = ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
+ Drawable tileIcon = mController.getWalletClient().getTileIcon();
+ state.icon =
+ tileIcon == null
+ ? ResourceIcon.get(R.drawable.ic_wallet_lockscreen)
+ : new DrawableIcon(tileIcon);
boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
if (mController.getWalletClient().isWalletServiceAvailable()
&& mController.getWalletClient().isWalletFeatureAvailable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index c09f98d..5afdc38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -66,7 +66,6 @@
import com.android.internal.widget.ViewClippingUtil;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
@@ -130,7 +129,6 @@
private String mRestingIndication;
private String mAlignmentIndication;
private CharSequence mTransientIndication;
- private boolean mTransientTextIsError;
protected ColorStateList mInitialTextColorState;
private boolean mVisible;
private boolean mHideTransientMessageOnScreenOff;
@@ -382,8 +380,7 @@
private void updateTransient() {
if (!TextUtils.isEmpty(mTransientIndication)) {
- mRotateTextViewController.showTransient(mTransientIndication,
- mTransientTextIsError);
+ mRotateTextViewController.showTransient(mTransientIndication);
} else {
mRotateTextViewController.hideTransient();
}
@@ -421,7 +418,8 @@
INDICATION_TYPE_ALIGNMENT,
new KeyguardIndication.Builder()
.setMessage(mAlignmentIndication)
- .setTextColor(Utils.getColorError(mContext))
+ .setTextColor(ColorStateList.valueOf(
+ mContext.getColor(R.color.misalignment_text_color)))
.build(),
true);
} else {
@@ -594,7 +592,6 @@
boolean isError, boolean hideOnScreenOff) {
mTransientIndication = transientIndication;
mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
- mTransientTextIsError = isError;
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
@@ -811,7 +808,6 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardIndicationController:");
- pw.println(" mTransientTextIsError: " + mTransientTextIsError);
pw.println(" mInitialTextColorState: " + mInitialTextColorState);
pw.println(" mPowerPluggedInWired: " + mPowerPluggedInWired);
pw.println(" mPowerPluggedIn: " + mPowerPluggedIn);
@@ -886,7 +882,10 @@
return;
}
- if (biometricSourceType == BiometricSourceType.FACE && shouldSuppressFaceMsg()) {
+ if (biometricSourceType == BiometricSourceType.FACE
+ && shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
+ // suggest trying fingerprint
+ showTransientIndication(R.string.keyguard_try_fingerprint);
return;
}
@@ -913,6 +912,12 @@
if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
return;
}
+ if (biometricSourceType == BiometricSourceType.FACE
+ && shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
+ // suggest trying fingerprint
+ showTransientIndication(R.string.keyguard_try_fingerprint);
+ return;
+ }
if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
// The face timeout message is not very actionable, let's ask the user to
// manually retry.
@@ -958,18 +963,16 @@
|| msgId == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED);
}
- private boolean shouldSuppressFaceMsg() {
+ private boolean shouldSuppressFaceMsgAndShowTryFingerprintMsg() {
// For dual biometric, don't show face auth messages unless face auth was explicitly
// requested by the user.
- return mKeyguardUpdateMonitor.isUdfpsEnrolled()
- && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()
- && !mKeyguardUpdateMonitor.isFaceAuthUserRequested();
+ return mKeyguardUpdateMonitor.isFingerprintDetectionRunning()
+ && !mKeyguardUpdateMonitor.isFaceAuthUserRequested()
+ && mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ true /* isStrongBiometric */);
}
private boolean shouldSuppressFaceError(int msgId, KeyguardUpdateMonitor updateMonitor) {
- if (shouldSuppressFaceMsg()) {
- return true;
- }
// Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
// as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to
// pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index a2048e2..f6b16b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -21,6 +21,7 @@
import android.animation.ValueAnimator
import android.app.WallpaperManager
import android.os.SystemClock
+import android.os.Trace
import android.util.IndentingPrintWriter
import android.util.Log
import android.util.MathUtils
@@ -198,6 +199,7 @@
blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt()
val opaque = scrimsVisible && !blursDisabledForAppLaunch
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur)
blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque)
try {
if (root.isAttachedToWindow && root.windowToken != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index c4d1abc..6802472 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -223,8 +223,15 @@
* then abruptly showing AOD.
*/
public boolean shouldControlUnlockedScreenOff() {
- return getAlwaysOn() && mFeatureFlags.useNewLockscreenAnimations()
- && mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation();
+ return mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation();
+ }
+
+ /**
+ * Whether we're capable of controlling the screen off animation if we want to. This isn't
+ * possible if AOD isn't even enabled or if the flag is disabled.
+ */
+ public boolean canControlUnlockedScreenOff() {
+ return getAlwaysOn() && mFeatureFlags.useNewLockscreenAnimations();
}
private boolean getBoolean(String propName, int resId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 8e3aed4..16f8319 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -455,6 +455,10 @@
mWalletButton.setVisibility(GONE);
mIndicationArea.setPadding(0, 0, 0, 0);
} else {
+ Drawable tileIcon = mQuickAccessWalletController.getWalletClient().getTileIcon();
+ if (tileIcon != null) {
+ mWalletButton.setImageDrawable(tileIcon);
+ }
mWalletButton.setVisibility(VISIBLE);
mWalletButton.setOnClickListener(this::onWalletClick);
mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index fa5011e..ad4213d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -234,7 +234,9 @@
private int getClockY(float panelExpansion, float darkAmount) {
float clockYRegular = getExpandedPreferredClockY();
- float clockYBouncer = -mKeyguardStatusHeight;
+
+ // Dividing the height creates a smoother transition when the user swipes up to unlock
+ float clockYBouncer = -mKeyguardStatusHeight / 3.0f;
// Move clock up while collapsing the shade
float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(panelExpansion);
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 5ebfacf..7fdc2e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -2788,7 +2788,6 @@
private int calculatePanelHeightShade() {
int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin();
int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
- maxHeight += mNotificationStackScrollLayoutController.getTopPaddingOverflow();
if (mBarState == KEYGUARD) {
int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight()
@@ -3478,6 +3477,14 @@
return !isFullWidth() || !mShowIconsWhenExpanded;
}
+ public final QS.ScrollListener mScrollListener = scrollY -> {
+ if (scrollY > 0 && !mQsFullyExpanded) {
+ if (DEBUG) Log.d(TAG, "Scrolling while not expanded. Forcing expand");
+ // If we are scrolling QS, we should be fully expanded.
+ expandWithQs();
+ }
+ };
+
private final FragmentListener mFragmentListener = new FragmentListener() {
@Override
public void onFragmentViewCreated(String tag, Fragment fragment) {
@@ -3507,6 +3514,7 @@
});
mLockscreenShadeTransitionController.setQS(mQs);
mNotificationStackScrollLayoutController.setQsContainer((ViewGroup) mQs.getView());
+ mQs.setScrollListener(mScrollListener);
updateQsExpansion();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 6b00dd4..c1f3762 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -45,7 +45,8 @@
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val statusBarStateControllerImpl: StatusBarStateControllerImpl,
private val keyguardViewMediatorLazy: dagger.Lazy<KeyguardViewMediator>,
- private val keyguardStateController: KeyguardStateController
+ private val keyguardStateController: KeyguardStateController,
+ private val dozeParameters: dagger.Lazy<DozeParameters>
) : WakefulnessLifecycle.Observer {
private val handler = Handler()
@@ -146,7 +147,7 @@
}
override fun onStartedGoingToSleep() {
- if (shouldPlayUnlockedScreenOffAnimation()) {
+ if (dozeParameters.get().shouldControlUnlockedScreenOff()) {
lightRevealAnimationPlaying = true
lightRevealAnimator.start()
@@ -164,6 +165,10 @@
* on the current state of the device.
*/
fun shouldPlayUnlockedScreenOffAnimation(): Boolean {
+ if (!dozeParameters.get().canControlUnlockedScreenOff()) {
+ return false
+ }
+
// We only play the unlocked screen off animation if we are... unlocked.
if (statusBarStateControllerImpl.state != StatusBarState.SHADE) {
return false
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 2dcc43c..dc240db 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -136,7 +136,7 @@
}
};
- walletView.getAppButton().setOnClickListener(
+ walletView.setShowWalletAppOnClickListener(
v -> {
if (mWalletClient.createWalletIntent() == null) {
Log.w(TAG, "Unable to create wallet app intent.");
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index 0c53477..0a09d59 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -22,6 +22,7 @@
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -54,6 +55,8 @@
private final TextView mCardLabel;
// Displays at the bottom of the screen, allow user to enter the default wallet app.
private final Button mAppButton;
+ // Displays on the top right of the screen, allow user to enter the default wallet app.
+ private final Button mToolbarAppButton;
// Displays underneath the carousel, allow user to unlock device, verify card, etc.
private final Button mActionButton;
private final Interpolator mOutInterpolator;
@@ -61,10 +64,10 @@
private final ViewGroup mCardCarouselContainer;
private final TextView mErrorView;
private final ViewGroup mEmptyStateView;
- private CharSequence mCenterCardText;
private boolean mIsDeviceLocked = false;
private boolean mIsUdfpsEnabled = false;
private OnClickListener mDeviceLockedActionOnClickListener;
+ private OnClickListener mShowWalletAppOnClickListener;
public WalletView(Context context) {
this(context, null);
@@ -79,6 +82,7 @@
mIcon = requireViewById(R.id.icon);
mCardLabel = requireViewById(R.id.label);
mAppButton = requireViewById(R.id.wallet_app_button);
+ mToolbarAppButton = requireViewById(R.id.wallet_toolbar_app_button);
mActionButton = requireViewById(R.id.wallet_action_button);
mErrorView = requireViewById(R.id.error_view);
mEmptyStateView = requireViewById(R.id.wallet_empty_state);
@@ -94,6 +98,43 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ updateViewForOrientation(newConfig.orientation);
+ }
+
+ private void updateViewForOrientation(@Configuration.Orientation int orientation) {
+ if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+ renderViewPortrait();
+ } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ renderViewLandscape();
+ }
+ ViewGroup.LayoutParams params = mCardCarouselContainer.getLayoutParams();
+ if (params instanceof MarginLayoutParams) {
+ ((MarginLayoutParams) params).topMargin =
+ getResources().getDimensionPixelSize(
+ R.dimen.wallet_card_carousel_container_top_margin);
+ }
+ }
+
+ private void renderViewPortrait() {
+ mAppButton.setVisibility(VISIBLE);
+ mToolbarAppButton.setVisibility(GONE);
+ mCardLabel.setVisibility(VISIBLE);
+ requireViewById(R.id.dynamic_placeholder).setVisibility(VISIBLE);
+
+ mAppButton.setOnClickListener(mShowWalletAppOnClickListener);
+ }
+
+ private void renderViewLandscape() {
+ mToolbarAppButton.setVisibility(VISIBLE);
+ mAppButton.setVisibility(GONE);
+ mCardLabel.setVisibility(GONE);
+ requireViewById(R.id.dynamic_placeholder).setVisibility(GONE);
+
+ mToolbarAppButton.setOnClickListener(mShowWalletAppOnClickListener);
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent event) {
// Forward touch events to card carousel to allow for swiping outside carousel bounds.
return mCardCarousel.onTouchEvent(event) || super.onTouchEvent(event);
@@ -137,10 +178,12 @@
mIsDeviceLocked = isDeviceLocked;
mIsUdfpsEnabled = isUdfpsEnabled;
mCardCarouselContainer.setVisibility(VISIBLE);
+ mCardCarousel.setVisibility(VISIBLE);
mErrorView.setVisibility(GONE);
mEmptyStateView.setVisibility(GONE);
mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex)));
mCardLabel.setText(getLabelText(data.get(selectedIndex)));
+ updateViewForOrientation(getResources().getConfiguration().orientation);
renderActionButton(data.get(selectedIndex), isDeviceLocked, mIsUdfpsEnabled);
if (shouldAnimate) {
animateViewsShown(mIcon, mCardLabel, mActionButton);
@@ -190,6 +233,10 @@
mDeviceLockedActionOnClickListener = onClickListener;
}
+ void setShowWalletAppOnClickListener(OnClickListener onClickListener) {
+ mShowWalletAppOnClickListener = onClickListener;
+ }
+
void hide() {
setVisibility(GONE);
}
@@ -206,10 +253,6 @@
return mCardCarousel;
}
- Button getAppButton() {
- return mAppButton;
- }
-
Button getActionButton() {
return mActionButton;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 09e6940..06e27b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -38,7 +38,6 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Insets;
-import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.testing.AndroidTestingRunner;
@@ -49,7 +48,6 @@
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
-import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@@ -87,7 +85,6 @@
private final List<AccessibilityTarget> mTargets = new ArrayList<>(
Collections.singletonList(mock(AccessibilityTarget.class)));
- private final Rect mAvailableBounds = new Rect(100, 200, 300, 400);
private final Position mPlaceholderPosition = new Position(0.0f, 0.0f);
@Mock
@@ -144,6 +141,7 @@
@Test
public void initListView_success() {
+ assertThat(mListView.getCompatAccessibilityDelegate()).isNotNull();
assertThat(mMenuView.getChildCount()).isEqualTo(1);
}
@@ -370,90 +368,6 @@
}
@Test
- public void getAccessibilityActionList_matchResult() {
- final AccessibilityNodeInfo info = new AccessibilityNodeInfo();
-
- mMenuView.onInitializeAccessibilityNodeInfo(info);
-
- assertThat(info.getActionList().size()).isEqualTo(5);
- }
-
- @Test
- public void accessibilityActionMove_halfOval_moveTopLeft_success() {
- doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
- mMenuView.setShapeType(/* halfOvalShape */ 1);
-
- final boolean moveTopLeftAction =
- mMenuView.performAccessibilityAction(R.id.action_move_top_left, null);
-
- assertThat(moveTopLeftAction).isTrue();
- assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
- verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
- }
-
- @Test
- public void accessibilityActionMove_halfOval_moveTopRight_success() {
- doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
- mMenuView.setShapeType(/* halfOvalShape */ 1);
-
- final boolean moveTopRightAction =
- mMenuView.performAccessibilityAction(R.id.action_move_top_right, null);
-
- assertThat(moveTopRightAction).isTrue();
- assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
- verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
- }
-
- @Test
- public void accessibilityActionMove_halfOval_moveBottomLeft_success() {
- doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
- mMenuView.setShapeType(/* halfOvalShape */ 1);
-
- final boolean moveBottomLeftAction =
- mMenuView.performAccessibilityAction(R.id.action_move_bottom_left, null);
-
- assertThat(moveBottomLeftAction).isTrue();
- assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
- verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
- }
-
- @Test
- public void accessibilityActionMove_halfOval_moveBottomRight_success() {
- doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
- mMenuView.setShapeType(/* halfOvalShape */ 1);
-
- final boolean moveBottomRightAction =
- mMenuView.performAccessibilityAction(R.id.action_move_bottom_right, null);
-
- assertThat(moveBottomRightAction).isTrue();
- assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
- verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
- }
-
- @Test
- public void accessibilityActionMove_halfOval_moveOutEdgeAndShow_success() {
- doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
- mMenuView.setShapeType(/* halfOvalShape */ 1);
-
- final boolean moveOutEdgeAndShowAction =
- mMenuView.performAccessibilityAction(R.id.action_move_out_edge_and_show, null);
-
- assertThat(moveOutEdgeAndShowAction).isTrue();
- assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
- }
-
- @Test
- public void setupAccessibilityActions_oval_hasActionMoveToEdgeAndHide() {
- final AccessibilityNodeInfo info = new AccessibilityNodeInfo();
- mMenuView.setShapeType(/* ovalShape */ 0);
-
- mMenuView.onInitializeAccessibilityNodeInfo(info);
-
- assertThat(info.getActionList().stream().anyMatch(
- action -> action.getId() == R.id.action_move_to_edge_and_hide)).isTrue();
- }
-
- @Test
public void onTargetsChanged_exceedAvailableHeight_overScrollAlways() {
doReturn(true).when(mMenuView).hasExceededMaxLayoutHeight();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java
new file mode 100644
index 0000000..dae4364
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.accessibility.floatingmenu;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/** Tests for {@link ItemDelegateCompat}. */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ItemDelegateCompatTest extends SysuiTestCase {
+ @Rule
+ public MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private WindowManager mWindowManager;
+
+ private RecyclerView mListView;
+ private AccessibilityFloatingMenuView mMenuView;
+ private ItemDelegateCompat mItemDelegateCompat;
+ private final Rect mAvailableBounds = new Rect(100, 200, 300, 400);
+ private final Position mPlaceholderPosition = new Position(0.0f, 0.0f);
+
+ @Before
+ public void setUp() {
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ doAnswer(invocation -> wm.getMaximumWindowMetrics()).when(
+ mWindowManager).getMaximumWindowMetrics();
+ mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
+
+ mListView = new RecyclerView(mContext);
+ mMenuView =
+ spy(new AccessibilityFloatingMenuView(mContext, mPlaceholderPosition, mListView));
+ mItemDelegateCompat =
+ new ItemDelegateCompat(new RecyclerViewAccessibilityDelegate(mListView), mMenuView);
+ }
+
+ @Test
+ public void getAccessibilityActionList_matchResult() {
+ final AccessibilityNodeInfoCompat info =
+ new AccessibilityNodeInfoCompat(new AccessibilityNodeInfo());
+
+ mItemDelegateCompat.onInitializeAccessibilityNodeInfo(mListView, info);
+
+ assertThat(info.getActionList().size()).isEqualTo(5);
+ }
+
+ @Test
+ public void performAccessibilityMoveTopLeftAction_halfOval_success() {
+ doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
+ mMenuView.setShapeType(/* halfOvalShape */ 1);
+
+ final boolean moveTopLeftAction =
+ mItemDelegateCompat.performAccessibilityAction(mListView, R.id.action_move_top_left,
+ null);
+
+ assertThat(moveTopLeftAction).isTrue();
+ assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
+ verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
+ }
+
+ @Test
+ public void performAccessibilityMoveTopRightAction_halfOval_success() {
+ doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
+ mMenuView.setShapeType(/* halfOvalShape */ 1);
+
+ final boolean moveTopRightAction =
+ mItemDelegateCompat.performAccessibilityAction(mListView,
+ R.id.action_move_top_right, null);
+
+ assertThat(moveTopRightAction).isTrue();
+ assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
+ verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
+ }
+
+ @Test
+ public void performAccessibilityMoveBottomLeftAction_halfOval_success() {
+ doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
+ mMenuView.setShapeType(/* halfOvalShape */ 1);
+
+ final boolean moveBottomLeftAction =
+ mItemDelegateCompat.performAccessibilityAction(mListView,
+ R.id.action_move_bottom_left, null);
+
+ assertThat(moveBottomLeftAction).isTrue();
+ assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
+ verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
+ }
+
+ @Test
+ public void performAccessibilityMoveBottomRightAction_halfOval_success() {
+ doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
+ mMenuView.setShapeType(/* halfOvalShape */ 1);
+
+ final boolean moveBottomRightAction =
+ mItemDelegateCompat.performAccessibilityAction(mListView,
+ R.id.action_move_bottom_right, null);
+
+ assertThat(moveBottomRightAction).isTrue();
+ assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
+ verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
+ }
+
+ @Test
+ public void performAccessibilityMoveOutEdgeAction_halfOval_success() {
+ doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
+ mMenuView.setShapeType(/* halfOvalShape */ 1);
+
+ final boolean moveOutEdgeAndShowAction =
+ mItemDelegateCompat.performAccessibilityAction(mListView,
+ R.id.action_move_out_edge_and_show, null);
+
+ assertThat(moveOutEdgeAndShowAction).isTrue();
+ assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
+ }
+
+ @Test
+ public void setupAccessibilityActions_oval_hasActionMoveToEdgeAndHide() {
+ final AccessibilityNodeInfoCompat info =
+ new AccessibilityNodeInfoCompat(new AccessibilityNodeInfo());
+ mMenuView.setShapeType(/* ovalShape */ 0);
+
+ mItemDelegateCompat.onInitializeAccessibilityNodeInfo(mListView, info);
+
+ assertThat(info.getActionList().stream().anyMatch(
+ action -> action.getId() == R.id.action_move_to_edge_and_hide)).isTrue();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 3eb1a9e..546038e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -31,6 +31,7 @@
import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
@@ -77,6 +78,8 @@
private HistoryTracker mHistoryTracker;
@Mock
private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private AccessibilityManager mAccessibilityManager;
private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@@ -101,7 +104,8 @@
when(mKeyguardStateController.isShowing()).thenReturn(true);
mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager,
mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier,
- mHistoryTracker, mKeyguardStateController, false);
+ mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
+ false);
ArgumentCaptor<GestureFinalizedListener> gestureCompleteListenerCaptor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
new file mode 100644
index 0000000..86243b5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 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.classifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyDouble;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class BrightLineFalsingManagerTest extends SysuiTestCase {
+ private BrightLineFalsingManager mBrightLineFalsingManager;
+ @Mock
+ private FalsingDataProvider mFalsingDataProvider;
+ private final DockManagerFake mDockManager = new DockManagerFake();
+ private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
+ private final Set<FalsingClassifier> mClassifiers = new HashSet<>();
+ @Mock
+ private SingleTapClassifier mSingleTapClassifier;
+ @Mock
+ private DoubleTapClassifier mDoubleTapClassifier;
+ @Mock
+ private FalsingClassifier mClassifierA;
+ private final List<MotionEvent> mMotionEventList = new ArrayList<>();
+ @Mock
+ private HistoryTracker mHistoryTracker;
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private AccessibilityManager mAccessibilityManager;
+
+ private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
+ private final FalsingClassifier.Result mFalsedResult =
+ FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
+ .thenReturn(mFalsedResult);
+ when(mSingleTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
+ when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
+ .thenReturn(mFalsedResult);
+ mClassifiers.add(mClassifierA);
+ when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager,
+ mMetricsLogger, mClassifiers, mSingleTapClassifier, mDoubleTapClassifier,
+ mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
+ false);
+ }
+
+ @Test
+ public void testA11yDisablesGesture() {
+ assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
+ when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
+ }
+
+
+ @Test
+ public void testA11yDisablesTap() {
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+ when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+ }
+
+
+ @Test
+ public void testA11yDisablesDoubleTap() {
+ assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
+ when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
+ }
+
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
index 5157668..61b4041 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -211,7 +211,7 @@
reset(mExecutor);
// WHEN we have a transient message
- mController.showTransient(TEST_MESSAGE_2, false);
+ mController.showTransient(TEST_MESSAGE_2);
// THEN
// - we immediately update
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
index ba4fc0a..e9e965e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -19,9 +19,9 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -35,6 +35,7 @@
@Mock
private lateinit var playerIsPlaying: MediaControlPanel
+ private var systemClock: FakeSystemClock = FakeSystemClock()
@JvmField
@Rule
@@ -59,8 +60,8 @@
val playerIsRemote = mock(MediaControlPanel::class.java)
val dataIsRemote = createMediaData("app2", PLAYING, !LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
+ MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote, systemClock)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock)
val players = MediaPlayerData.players()
assertThat(players).hasSize(2)
@@ -68,7 +69,6 @@
}
@Test
- @Ignore("Flaky")
fun switchPlayersPlaying() {
val playerIsPlaying1 = mock(MediaControlPanel::class.java)
var dataIsPlaying1 = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION)
@@ -76,14 +76,19 @@
val playerIsPlaying2 = mock(MediaControlPanel::class.java)
var dataIsPlaying2 = createMediaData("app2", !PLAYING, LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
- MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock)
+ systemClock.advanceTime(1)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock)
+ systemClock.advanceTime(1)
dataIsPlaying1 = createMediaData("app1", !PLAYING, LOCAL, !RESUMPTION)
dataIsPlaying2 = createMediaData("app2", PLAYING, LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
- MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock)
+ systemClock.advanceTime(1)
+
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock)
+ systemClock.advanceTime(1)
val players = MediaPlayerData.players()
assertThat(players).hasSize(2)
@@ -109,12 +114,15 @@
val playerUndetermined = mock(MediaControlPanel::class.java)
val dataUndetermined = createMediaData("app6", UNDETERMINED, LOCAL, RESUMPTION)
- MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal)
- MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote)
- MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
- MediaPlayerData.addMediaPlayer("2", dataIsPlayingAndRemote, playerIsPlayingAndRemote)
- MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined)
+ MediaPlayerData.addMediaPlayer(
+ "3", dataIsStoppedAndLocal, playerIsStoppedAndLocal, systemClock)
+ MediaPlayerData.addMediaPlayer(
+ "5", dataIsStoppedAndRemote, playerIsStoppedAndRemote, systemClock)
+ MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume, systemClock)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock)
+ MediaPlayerData.addMediaPlayer(
+ "2", dataIsPlayingAndRemote, playerIsPlayingAndRemote, systemClock)
+ MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined, systemClock)
val players = MediaPlayerData.players()
assertThat(players).hasSize(6)
@@ -130,8 +138,14 @@
val data = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer(keyA, data, playerIsPlaying)
- MediaPlayerData.addMediaPlayer(keyB, data, playerIsPlaying)
+ assertThat(MediaPlayerData.players()).hasSize(0)
+
+ MediaPlayerData.addMediaPlayer(keyA, data, playerIsPlaying, systemClock)
+ systemClock.advanceTime(1)
+
+ assertThat(MediaPlayerData.players()).hasSize(1)
+ MediaPlayerData.addMediaPlayer(keyB, data, playerIsPlaying, systemClock)
+ systemClock.advanceTime(1)
assertThat(MediaPlayerData.players()).hasSize(2)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java
index 00e012e..0d1749c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java
@@ -156,7 +156,7 @@
@Test
public void testShouldCancelJob_noRemainingWidgets_longTimeElapsed_shouldCancel() {
assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(
- new HashMap<>(), 10, Duration.ofHours(25).toMillis())).isTrue();
+ new HashMap<>(), 10, Duration.ofHours(50).toMillis())).isTrue();
}
@Test
@@ -171,7 +171,7 @@
Map<String, Set<String>> remainingWidgets = new HashMap<>();
remainingWidgets.put(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(
- remainingWidgets, 10, 1000 * 60 * 60 * 25)).isTrue();
+ remainingWidgets, 10, Duration.ofHours(50).toMillis())).isTrue();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index e4e8cf0..21c5925 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -236,6 +236,21 @@
// No messages count.
assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility());
+ mHeight = getSizeInDp(R.dimen.required_height_for_medium) - 1;
+ RemoteViews smallViewHorizontal = getPeopleTileViewHelper(
+ tileWithLastInteraction).getViews();
+ View smallResultHorizontal = smallViewHorizontal.apply(mContext, null);
+
+ // Show name over predefined icon.
+ assertEquals(View.VISIBLE, smallResultHorizontal.findViewById(R.id.name).getVisibility());
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.predefined_icon).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.person_icon).getVisibility());
+ // No messages count.
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.messages_count).getVisibility());
mWidth = getSizeInDp(R.dimen.required_width_for_large);
mHeight = getSizeInDp(R.dimen.required_height_for_large);
@@ -292,6 +307,22 @@
// No messages count.
assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility());
+ mHeight = getSizeInDp(R.dimen.required_height_for_medium) - 1;
+ RemoteViews smallViewHorizontal = getPeopleTileViewHelper(
+ tileWithAvailabilityAndNewStory).getViews();
+ View smallResultHorizontal = smallViewHorizontal.apply(mContext, null);
+
+ // Show name over predefined icon.
+ assertEquals(View.VISIBLE, smallResultHorizontal.findViewById(R.id.name).getVisibility());
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.predefined_icon).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.person_icon).getVisibility());
+ // No messages count.
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.messages_count).getVisibility());
+
mWidth = getSizeInDp(R.dimen.required_width_for_large);
mHeight = getSizeInDp(R.dimen.required_height_for_large);
RemoteViews largeView = getPeopleTileViewHelper(tileWithAvailabilityAndNewStory).getViews();
@@ -348,6 +379,22 @@
// No messages count.
assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility());
+ mHeight = getSizeInDp(R.dimen.required_height_for_medium) - 1;
+ RemoteViews smallViewHorizontal = getPeopleTileViewHelper(
+ tileWithStatusTemplate).getViews();
+ View smallResultHorizontal = smallViewHorizontal.apply(mContext, null);
+
+ // Show name over predefined icon.
+ assertEquals(View.GONE, smallResultHorizontal.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.predefined_icon).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.person_icon).getVisibility());
+ // No messages count.
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.messages_count).getVisibility());
+
mWidth = getSizeInDp(R.dimen.required_width_for_large);
mHeight = getSizeInDp(R.dimen.required_height_for_large);
RemoteViews largeView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews();
@@ -407,6 +454,22 @@
// No messages count.
assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility());
+ mHeight = getSizeInDp(R.dimen.required_height_for_medium) - 1;
+ RemoteViews smallViewHorizontal = getPeopleTileViewHelper(
+ tileWithStatusTemplate).getViews();
+ View smallResultHorizontal = smallViewHorizontal.apply(mContext, null);
+
+ // Show name over predefined icon.
+ assertEquals(View.GONE, smallResultHorizontal.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.predefined_icon).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE,
+ smallResultHorizontal.findViewById(R.id.person_icon).getVisibility());
+ // No messages count.
+ assertEquals(View.GONE,
+ smallResultHorizontal.findViewById(R.id.messages_count).getVisibility());
+
mWidth = getSizeInDp(R.dimen.required_width_for_large);
mHeight = getSizeInDp(R.dimen.required_height_for_large);
RemoteViews largeView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index ddad758..05bef4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -144,6 +144,7 @@
private static final String TEST_PACKAGE_A = "com.android.systemui.tests";
private static final String TEST_PACKAGE_B = "com.test.package_b";
+ private static final String TEST_PACKAGE_C = "com.test.package_c";
private static final String TEST_CHANNEL_ID = "channel_id";
private static final String TEST_CHANNEL_NAME = "channel_name";
private static final String TEST_PARENT_CHANNEL_ID = "parent_channel_id";
@@ -161,6 +162,7 @@
private static final int WIDGET_ID_15 = 15;
private static final String SHORTCUT_ID = "101";
private static final String OTHER_SHORTCUT_ID = "102";
+ private static final String THIRD_SHORTCUT_ID = "103";
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
private static final String NOTIFICATION_CONTENT_1 = "message text 1";
private static final Uri URI = Uri.parse("fake_uri");
@@ -211,6 +213,12 @@
String.valueOf(WIDGET_ID_15), String.valueOf(WIDGET_ID_WITH_DIFFERENT_URI)
);
+ private static final Map<String, String> WIDGETS_MAPPING_CROSS_MAPPING = Map.of(
+ String.valueOf(WIDGET_ID_WITH_SHORTCUT), String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
+ String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT), String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT),
+ String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS), String.valueOf(WIDGET_ID_WITH_SHORTCUT)
+ );
+
private ShortcutInfo mShortcutInfo;
private NotificationEntry mNotificationEntry;
@@ -1461,6 +1469,33 @@
}
@Test
+ public void testRemapWidgetFiles_crossMapping() {
+ setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT, URI);
+ setStorageForTile(OTHER_SHORTCUT_ID, TEST_PACKAGE_B, WIDGET_ID_WITHOUT_SHORTCUT, URI);
+ setStorageForTile(THIRD_SHORTCUT_ID, TEST_PACKAGE_C, WIDGET_ID_WITH_KEY_IN_OPTIONS, URI);
+
+ mManager.remapWidgetFiles(WIDGETS_MAPPING_CROSS_MAPPING);
+
+ SharedPreferences sp1 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_SHORTCUT), Context.MODE_PRIVATE);
+ PeopleTileKey key1 = SharedPreferencesHelper.getPeopleTileKey(sp1);
+ assertThat(key1.getShortcutId()).isEqualTo(THIRD_SHORTCUT_ID);
+ assertThat(key1.getPackageName()).isEqualTo(TEST_PACKAGE_C);
+
+ SharedPreferences sp2 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT), Context.MODE_PRIVATE);
+ PeopleTileKey key2 = SharedPreferencesHelper.getPeopleTileKey(sp2);
+ assertThat(key2.getShortcutId()).isEqualTo(OTHER_SHORTCUT_ID);
+ assertThat(key2.getPackageName()).isEqualTo(TEST_PACKAGE_B);
+
+ SharedPreferences sp4 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS), Context.MODE_PRIVATE);
+ PeopleTileKey key4 = SharedPreferencesHelper.getPeopleTileKey(sp4);
+ assertThat(key4.getShortcutId()).isEqualTo(SHORTCUT_ID);
+ assertThat(key4.getPackageName()).isEqualTo(TEST_PACKAGE_A);
+ }
+
+ @Test
public void testRemapSharedFile() {
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_8, URI);
setStorageForTile(OTHER_SHORTCUT_ID, TEST_PACKAGE_B, WIDGET_ID_11, URI);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index b1e67f5..a70c2be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -43,6 +43,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Handler;
import android.service.quickaccesswallet.GetWalletCardsError;
@@ -93,6 +94,7 @@
private static final Icon CARD_IMAGE =
Icon.createWithBitmap(Bitmap.createBitmap(70, 50, Bitmap.Config.ARGB_8888));
+ private final Drawable mTileIcon = mContext.getDrawable(R.drawable.ic_qs_wallet);
private final Intent mWalletIntent = new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
.setComponent(new ComponentName(mContext.getPackageName(), "WalletActivity"));
@@ -137,6 +139,7 @@
when(mHost.getContext()).thenReturn(mSpiedContext);
when(mHost.getUiEventLogger()).thenReturn(mUiEventLogger);
when(mQuickAccessWalletClient.getServiceLabel()).thenReturn(LABEL);
+ when(mQuickAccessWalletClient.getTileIcon()).thenReturn(mTileIcon);
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true);
@@ -255,6 +258,18 @@
@Test
public void testHandleUpdateState_updateLabelAndIcon() {
QSTile.State state = new QSTile.State();
+
+ mTile.handleUpdateState(state, null);
+
+ assertEquals(LABEL, state.label.toString());
+ assertTrue(state.label.toString().contentEquals(state.contentDescription));
+ assertEquals(mTileIcon, state.icon.getDrawable(mContext));
+ }
+
+ @Test
+ public void testHandleUpdateState_updateLabelAndIcon_noIconFromApi() {
+ when(mQuickAccessWalletClient.getTileIcon()).thenReturn(null);
+ QSTile.State state = new QSTile.State();
QSTile.Icon icon = QSTileImpl.ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
mTile.handleUpdateState(state, null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index b8db115..1ba3831 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -72,7 +72,6 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -248,8 +247,8 @@
verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
mContext.getResources().getString(R.string.dock_alignment_slow_charging));
- assertThat(mKeyguardIndicationCaptor.getValue().getTextColor())
- .isEqualTo(Utils.getColorError(mContext));
+ assertThat(mKeyguardIndicationCaptor.getValue().getTextColor().getDefaultColor())
+ .isEqualTo(mContext.getColor(R.color.misalignment_text_color));
}
@Test
@@ -265,8 +264,8 @@
verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
mContext.getResources().getString(R.string.dock_alignment_not_charging));
- assertThat(mKeyguardIndicationCaptor.getValue().getTextColor())
- .isEqualTo(Utils.getColorError(mContext));
+ assertThat(mKeyguardIndicationCaptor.getValue().getTextColor().getDefaultColor())
+ .isEqualTo(mContext.getColor(R.color.misalignment_text_color));
}
@Test
@@ -680,7 +679,7 @@
private void verifyHideIndication(int type) {
if (type == INDICATION_TYPE_TRANSIENT) {
verify(mRotateTextViewController).hideTransient();
- verify(mRotateTextViewController, never()).showTransient(anyString(), anyBoolean());
+ verify(mRotateTextViewController, never()).showTransient(anyString());
} else {
verify(mRotateTextViewController).hideIndication(type);
verify(mRotateTextViewController, never()).updateIndication(eq(type),
@@ -689,10 +688,10 @@
}
private void verifyTransientMessage(String message) {
- verify(mRotateTextViewController).showTransient(eq(message), anyBoolean());
+ verify(mRotateTextViewController).showTransient(eq(message));
}
private void verifyNoTransientMessage() {
- verify(mRotateTextViewController, never()).showTransient(any(), anyBoolean());
+ verify(mRotateTextViewController, never()).showTransient(any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 226c466..690b841 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -323,7 +323,8 @@
// WHEN the clock position algorithm is run
positionClock();
// THEN the notif padding is zero.
- assertThat(mClockPosition.stackScrollerPadding).isEqualTo(0);
+ assertThat(mClockPosition.stackScrollerPadding).isEqualTo(
+ (int) (mKeyguardStatusHeight * .667f));
}
@Test
diff --git a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
index ea2c7d2..2673cd1 100644
--- a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
+++ b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
@@ -30,6 +30,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.InputDevice;
+import android.view.KeyCharacterMap;
import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants;
@@ -55,7 +56,6 @@
*/
private static final int EVENT_META_STATE = 0;
private static final int EVENT_BUTTON_STATE = 0;
- private static final int EVENT_DEVICE_ID = 0;
private static final int EVENT_EDGE_FLAGS = 0;
private static final int EVENT_SOURCE = InputDevice.SOURCE_TOUCHSCREEN;
private static final int EVENT_FLAGS = 0;
@@ -122,9 +122,6 @@
return;
}
cancelAnyPendingInjectedEvents();
- // The events injected from outside of system_server are not trusted. Remove the flag to
- // prevent accessibility service from impersonating a real input device.
- policyFlags &= ~WindowManagerPolicyConstants.FLAG_INPUTFILTER_TRUSTED;
// Indicate that the input event is injected from accessibility, to let applications
// distinguish it from events injected by other means.
policyFlags |= WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY;
@@ -483,8 +480,8 @@
}
return MotionEvent.obtain(downTime, eventTime, action, touchPointsSize,
sPointerProps, sPointerCoords, EVENT_META_STATE, EVENT_BUTTON_STATE,
- EVENT_X_PRECISION, EVENT_Y_PRECISION, EVENT_DEVICE_ID, EVENT_EDGE_FLAGS,
- EVENT_SOURCE, EVENT_FLAGS);
+ EVENT_X_PRECISION, EVENT_Y_PRECISION, KeyCharacterMap.VIRTUAL_KEYBOARD,
+ EVENT_EDGE_FLAGS, EVENT_SOURCE, EVENT_FLAGS);
}
private static int findPointByStrokeId(TouchPoint[] touchPoints, int touchPointsSize,
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index a481a6a..f440ee8 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -61,7 +61,7 @@
private static final String MDNS_TAG = "mDnsConnector";
private static final boolean DBG = true;
- private static final long CLEANUP_DELAY_MS = 3000;
+ private static final long CLEANUP_DELAY_MS = 10000;
private final Context mContext;
private final NsdSettings mNsdSettings;
@@ -94,19 +94,25 @@
return NsdManager.nameOf(what);
}
- void maybeStartDaemon() {
+ private void maybeStartDaemon() {
mDaemon.maybeStart();
maybeScheduleStop();
}
- void maybeScheduleStop() {
+ private boolean isAnyRequestActive() {
+ return mIdToClientInfoMap.size() != 0;
+ }
+
+ private void scheduleStop() {
+ sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
+ }
+ private void maybeScheduleStop() {
if (!isAnyRequestActive()) {
- cancelStop();
- sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
+ scheduleStop();
}
}
- void cancelStop() {
+ private void cancelStop() {
this.removeMessages(NsdManager.DAEMON_CLEANUP);
}
@@ -164,11 +170,16 @@
if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
break;
}
+
cInfo = mClients.get(msg.replyTo);
if (cInfo != null) {
cInfo.expungeAllRequests();
mClients.remove(msg.replyTo);
}
+ //Last client
+ if (mClients.size() == 0) {
+ scheduleStop();
+ }
break;
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
AsyncChannel ac = new AsyncChannel();
@@ -235,7 +246,7 @@
public void exit() {
// TODO: it is incorrect to stop the daemon without expunging all requests
// and sending error callbacks to clients.
- maybeScheduleStop();
+ scheduleStop();
}
private boolean requestLimitReached(ClientInfo clientInfo) {
@@ -271,9 +282,6 @@
return NOT_HANDLED;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
return NOT_HANDLED;
- }
-
- switch (msg.what) {
case NsdManager.DISABLE:
//TODO: cleanup clients
transitionTo(mDisabledState);
@@ -531,10 +539,6 @@
}
}
- private boolean isAnyRequestActive() {
- return mIdToClientInfoMap.size() != 0;
- }
-
private String unescape(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); ++i) {
@@ -907,7 +911,6 @@
}
mClientIds.clear();
mClientRequests.clear();
- mNsdStateMachine.maybeScheduleStop();
}
// mClientIds is a sparse array of listener id -> mDnsClient id. For a given mDnsClient id,
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 8561042..8e53101 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -517,7 +517,7 @@
boolean shouldPinCamera = mConfiguredToPinCamera
&& DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
"pin_camera",
- SystemProperties.getBoolean("pinner.pin_camera", false));
+ SystemProperties.getBoolean("pinner.pin_camera", true));
if (shouldPinCamera) {
pinKeys.add(KEY_CAMERA);
} else if (DEBUG) {
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index c07d669..2a3358f 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -30,6 +30,7 @@
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS;
import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR;
@@ -519,7 +520,8 @@
options.setLaunchTaskId(info.mTaskId);
options.setTaskOverlay(true, true);
- dialogIntent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ dialogIntent.addFlags(
+ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | FLAG_ACTIVITY_NO_USER_ACTION);
dialogIntent.putExtra(EXTRA_PACKAGE_NAME, info.mPackageName);
if (sensors.size() == 1) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7c82502..0d35bb1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5684,16 +5684,6 @@
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
- try {
- if (uid != 0) { // bypass the root
- final String[] packageNames = getPackageManager().getPackagesForUid(uid);
- if (ArrayUtils.isEmpty(packageNames)) {
- // The uid is not existed or not visible to the caller.
- return PackageManager.PERMISSION_DENIED;
- }
- }
- } catch (RemoteException e) {
- }
return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags)
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
}
@@ -15558,13 +15548,11 @@
@Override
public List<ProcessMemoryState> getMemoryStateForProcesses() {
List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
- synchronized (mProcLock) {
- synchronized (mPidsSelfLocked) {
- for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
- final ProcessRecord r = mPidsSelfLocked.valueAt(i);
- processMemoryStates.add(new ProcessMemoryState(
- r.uid, r.getPid(), r.processName, r.mState.getCurAdj()));
- }
+ synchronized (mPidsSelfLocked) {
+ for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
+ final ProcessRecord r = mPidsSelfLocked.valueAt(i);
+ processMemoryStates.add(new ProcessMemoryState(
+ r.uid, r.getPid(), r.processName, r.mState.getCurAdj()));
}
}
return processMemoryStates;
@@ -16341,6 +16329,16 @@
return uidRecord.getCurCapability();
}
}
+
+ /**
+ * @return The PID list of the isolated process with packages matching the given uid.
+ */
+ @Nullable
+ public List<Integer> getIsolatedProcesses(int uid) {
+ synchronized (ActivityManagerService.this) {
+ return mProcessList.getIsolatedProcessesLocked(uid);
+ }
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d71919e..685d606 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -321,6 +321,8 @@
return runMemoryFactor(pw);
case "service-restart-backoff":
return runServiceRestartBackoff(pw);
+ case "get-isolated-pids":
+ return runGetIsolatedProcesses(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -3137,6 +3139,24 @@
}
}
+ private int runGetIsolatedProcesses(PrintWriter pw) throws RemoteException {
+ mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
+ "getIsolatedProcesses()");
+ final List<Integer> result = mInternal.mInternal.getIsolatedProcesses(
+ Integer.parseInt(getNextArgRequired()));
+ pw.print("[");
+ if (result != null) {
+ for (int i = 0, size = result.size(); i < size; i++) {
+ if (i > 0) {
+ pw.print(", ");
+ }
+ pw.print(result.get(i));
+ }
+ }
+ pw.println("]");
+ return 0;
+ }
+
private Resources getResources(PrintWriter pw) throws RemoteException {
// system resources does not contain all the device configuration, construct it manually.
Configuration config = mInterface.getConfiguration();
@@ -3467,6 +3487,8 @@
pw.println(" Toggles the restart backoff policy on/off for <PACKAGE_NAME>.");
pw.println(" show <PACKAGE_NAME>");
pw.println(" Shows the restart backoff policy state for <PACKAGE_NAME>.");
+ pw.println(" get-isolated-pids <UID>");
+ pw.println(" Get the PIDs of isolated processes with packages in this <UID>");
pw.println();
Intent.printIntentArgsHelp(pw, "");
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 317b775..8db7eea 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -212,6 +212,23 @@
}
};
+ private final OnPropertiesChangedListener mOnNativeBootFlagsChangedListener =
+ new OnPropertiesChangedListener() {
+ @Override
+ public void onPropertiesChanged(Properties properties) {
+ synchronized (mPhenotypeFlagLock) {
+ for (String name : properties.getKeyset()) {
+ if (KEY_FREEZER_DEBOUNCE_TIMEOUT.equals(name)) {
+ updateFreezerDebounceTimeout();
+ }
+ }
+ }
+ if (mTestCallback != null) {
+ mTestCallback.onPropertyChanged();
+ }
+ }
+ };
+
private final class SettingsContentObserver extends ContentObserver {
SettingsContentObserver() {
super(mAm.mHandler);
@@ -328,6 +345,10 @@
// TODO: initialize flags to default and only update them if values are set in DeviceConfig
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(), mOnFlagsChangedListener);
+ DeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ ActivityThread.currentApplication().getMainExecutor(),
+ mOnNativeBootFlagsChangedListener);
mAm.mContext.getContentResolver().registerContentObserver(
CACHED_APP_FREEZER_ENABLED_URI, false, mSettingsObserver);
synchronized (mPhenotypeFlagLock) {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 6cebf47..5cb6fd9 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1530,9 +1530,11 @@
state.setAdjTarget(null);
state.setEmpty(false);
state.setCached(false);
- state.setNoKillOnForcedAppStandbyAndIdle(false);
state.resetAllowStartFgsState();
- app.mOptRecord.setShouldNotFreeze(false);
+ if (!cycleReEval) {
+ // Don't reset this flag when doing cycles re-evaluation.
+ app.mOptRecord.setShouldNotFreeze(false);
+ }
final int appUid = app.info.uid;
final int logUid = mService.mCurOomAdjUid;
@@ -1983,6 +1985,11 @@
final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP;
+ if (client.mOptRecord.shouldNotFreeze()) {
+ // Propagate the shouldNotFreeze flag down the bindings.
+ app.mOptRecord.setShouldNotFreeze(true);
+ }
+
if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
continue;
@@ -2019,9 +2026,6 @@
// Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
- // Similarly, we shouldn't kill it when it's in forced-app-standby
- // mode and cached & idle state.
- app.mState.setNoKillOnForcedAppStandbyAndIdle(true);
}
// Not doing bind OOM management, so treat
// this guy more like a started service.
@@ -2226,9 +2230,6 @@
// unfrozen.
if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
- // Similarly, we shouldn't kill it when it's in forced-app-standby
- // mode and cached & idle state.
- app.mState.setNoKillOnForcedAppStandbyAndIdle(true);
}
}
if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
@@ -2302,6 +2303,10 @@
// we are going to consider it empty.
clientProcState = PROCESS_STATE_CACHED_EMPTY;
}
+ if (client.mOptRecord.shouldNotFreeze()) {
+ // Propagate the shouldNotFreeze flag down the bindings.
+ app.mOptRecord.setShouldNotFreeze(true);
+ }
String adjType = null;
if (adj > clientAdj) {
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 4455fd0..7e79ef5 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -333,6 +333,7 @@
if (errorId != null) {
info.append("ErrorId: ").append(errorId.toString()).append("\n");
}
+ info.append("Frozen: ").append(mApp.mOptRecord.isFrozen()).append("\n");
// Retrieve controller with max ANR delay from AnrControllers
// Note that we retrieve the controller before dumping stacks because dumping stacks can
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7c5d09c..b77270f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -56,6 +56,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityThread;
@@ -2988,6 +2989,22 @@
}
}
+ @Nullable
+ @GuardedBy("mService")
+ List<Integer> getIsolatedProcessesLocked(int uid) {
+ List<Integer> ret = null;
+ for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
+ final ProcessRecord app = mIsolatedProcesses.valueAt(i);
+ if (app.info.uid == uid) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+ ret.add(app.getPid());
+ }
+ }
+ return ret;
+ }
+
@GuardedBy("mService")
ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
@@ -4691,10 +4708,10 @@
final ApplicationInfo ai = AppGlobals.getPackageManager()
.getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
if (ai != null) {
- app.getThread().scheduleApplicationInfoChanged(ai);
if (ai.packageName.equals(app.info.packageName)) {
app.info = ai;
}
+ app.getThread().scheduleApplicationInfoChanged(ai);
targetProcesses.add(app.getWindowProcessController());
}
} catch (RemoteException e) {
@@ -4705,8 +4722,7 @@
});
}
- mService.mActivityTaskManager.updateAssetConfiguration(
- updateFrameworkRes ? null : targetProcesses);
+ mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
}
@GuardedBy("mService")
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index c113bc2..7520d88 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -357,13 +357,6 @@
@ElapsedRealtimeLong
private long mLastInvisibleTime;
- /**
- * Whether or not this process could be killed when it's in forced-app-standby mode
- * and cached & idle state.
- */
- @GuardedBy("mService")
- private boolean mNoKillOnForcedAppStandbyAndIdle;
-
// Below are the cached task info for OomAdjuster only
private static final int VALUE_INVALID = -1;
private static final int VALUE_FALSE = 0;
@@ -1134,16 +1127,6 @@
return mLastInvisibleTime;
}
- @GuardedBy("mService")
- void setNoKillOnForcedAppStandbyAndIdle(boolean shouldNotKill) {
- mNoKillOnForcedAppStandbyAndIdle = shouldNotKill;
- }
-
- @GuardedBy("mService")
- boolean shouldNotKillOnForcedAppStandbyAndIdle() {
- return mNoKillOnForcedAppStandbyAndIdle;
- }
-
@GuardedBy({"mService", "mProcLock"})
void dump(PrintWriter pw, String prefix, long nowUptime) {
if (mReportedInteraction || mFgInteractionTime != 0) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
index d69151d..0062d31 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
@@ -18,9 +18,11 @@
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMAGER_DIRTY;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_INSUFFICIENT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_BRIGHT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_FAST;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_SLOW;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
@@ -188,6 +190,8 @@
case FINGERPRINT_ACQUIRED_TOO_FAST:
case FINGERPRINT_ACQUIRED_VENDOR:
case FINGERPRINT_ACQUIRED_START:
+ case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+ case FINGERPRINT_ACQUIRED_IMMOBILE:
return true;
default:
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
index 0ae2e38..341aaa6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
@@ -78,7 +78,7 @@
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
} else if (aidlAcquiredInfo == AcquiredInfo.TOO_BRIGHT) {
// No framework constant available
- return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
+ return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_BRIGHT;
} else if (aidlAcquiredInfo == AcquiredInfo.IMMOBILE) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
} else if (aidlAcquiredInfo == AcquiredInfo.RETRYING_CAPTURE) {
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 168ca55..7d08ad0 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -903,9 +903,9 @@
userRecord.mManagerRecords.add(managerRecord);
mAllManagerRecords.put(binder, managerRecord);
- userRecord.mHandler.sendMessage(obtainMessage(UserHandler::notifyRoutesToManager,
- userRecord.mHandler, manager));
-
+ // Note: Features should be sent first before the routes. If not, the
+ // RouteCallback#onRoutesAdded() for system MR2 will never be called with initial routes
+ // due to the lack of features.
for (RouterRecord routerRecord : userRecord.mRouterRecords) {
// TODO: UserRecord <-> routerRecord, why do they reference each other?
// How about removing mUserRecord from routerRecord?
@@ -913,6 +913,9 @@
obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManager,
routerRecord.mUserRecord.mHandler, routerRecord, manager));
}
+
+ userRecord.mHandler.sendMessage(obtainMessage(UserHandler::notifyRoutesToManager,
+ userRecord.mHandler, manager));
}
private void unregisterManagerLocked(@NonNull IMediaRouter2Manager manager, boolean died) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d78fbdb..addcd0f 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -773,12 +773,13 @@
mAssistants.resetDefaultFromConfig();
continue;
}
+ // TODO(b/192450820): re-enable when "user set" isn't over triggering
//User selected different NAS, need onboarding
- enqueueNotificationInternal(getContext().getPackageName(),
+ /*enqueueNotificationInternal(getContext().getPackageName(),
getContext().getOpPackageName(), Binder.getCallingUid(),
Binder.getCallingPid(), TAG,
SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE,
- createNASUpgradeNotification(userId), userId);
+ createNASUpgradeNotification(userId), userId);*/
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index d2ed08f..d7b2449 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -989,7 +989,8 @@
SessionInfo info =
session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID);
if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
- && session.userId == userId && !session.hasParentSessionId()) {
+ && session.userId == userId && !session.hasParentSessionId()
+ && isCallingUidOwner(session)) {
result.add(info);
}
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index c842ff1..cb78636 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -737,31 +737,31 @@
continue;
}
- // New session cannot have same package name as one of the active sessions
- if (stagedSession.sessionContains(s -> s.getPackageName().equals(packageName))) {
- if (isRollback) {
- // If the new session is a rollback, then it gets priority. The existing
- // session is failed to unblock rollback.
- final StagedSession root = stagedSession;
- if (!ensureActiveApexSessionIsAborted(root)) {
- Slog.e(TAG, "Failed to abort apex session " + root.sessionId());
- // Safe to ignore active apex session abort failure since session
- // will be marked failed on next step and staging directory for session
- // will be deleted.
- }
- root.setSessionFailed(
- SessionInfo.STAGED_SESSION_CONFLICT,
- "Session was blocking rollback session: " + session.sessionId());
- Slog.i(TAG, "Session " + root.sessionId() + " is marked failed due to "
- + "blocking rollback session: " + session.sessionId());
- } else {
- throw new PackageManagerException(
- SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
- "Package: " + session.getPackageName() + " in session: "
- + session.sessionId()
- + " has been staged already by session: "
- + stagedSession.sessionId(), null);
+ if (isRollback && !isRollback(stagedSession)) {
+ // If the new session is a rollback, then it gets priority. The existing
+ // session is failed to reduce risk and avoid an SDK extension dependency
+ // violation.
+ final StagedSession root = stagedSession;
+ if (!ensureActiveApexSessionIsAborted(root)) {
+ Slog.e(TAG, "Failed to abort apex session " + root.sessionId());
+ // Safe to ignore active apex session abort failure since session
+ // will be marked failed on next step and staging directory for session
+ // will be deleted.
}
+ root.setSessionFailed(
+ SessionInfo.STAGED_SESSION_CONFLICT,
+ "Session was failed by rollback session: " + session.sessionId());
+ Slog.i(TAG, "Session " + root.sessionId() + " is marked failed due to "
+ + "rollback session: " + session.sessionId());
+ } else if (stagedSession.sessionContains(
+ s -> s.getPackageName().equals(packageName))) {
+ // New session cannot have same package name as one of the active sessions
+ throw new PackageManagerException(
+ SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+ "Package: " + session.getPackageName() + " in session: "
+ + session.sessionId()
+ + " has been staged already by session: "
+ + stagedSession.sessionId(), null);
}
// Staging multiple root sessions is not allowed if device doesn't support
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 7689f5f..18c45e4 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -32,6 +32,7 @@
import android.content.pm.ResolveInfo;
import android.location.LocationManagerInternal;
import android.net.Uri;
+import android.os.Binder;
import android.os.IBinder;
import android.os.PackageTagsList;
import android.os.Process;
@@ -72,6 +73,9 @@
private final Object mLock = new Object();
@NonNull
+ private final IBinder mToken = new Binder();
+
+ @NonNull
private final Context mContext;
@NonNull
@@ -180,6 +184,15 @@
}, UserHandle.SYSTEM);
initializeActivityRecognizersTags();
+
+ // If this device does not have telephony, restrict the phone call ops
+ if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+ appOps.setUserRestrictionForUser(AppOpsManager.OP_PHONE_CALL_MICROPHONE, true, mToken,
+ null, UserHandle.USER_ALL);
+ appOps.setUserRestrictionForUser(AppOpsManager.OP_PHONE_CALL_CAMERA, true, mToken,
+ null, UserHandle.USER_ALL);
+ }
}
private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index dd54529..d551f66 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2252,6 +2252,7 @@
}
final WindowManagerPolicy.StartingSurface surface;
+ final StartingData startingData = mStartingData;
if (mStartingData != null) {
surface = mStartingSurface;
mStartingData = null;
@@ -2278,7 +2279,7 @@
final Runnable removeSurface = () -> {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface);
try {
- surface.remove(prepareAnimation);
+ surface.remove(prepareAnimation && startingData.needRevealAnimation());
} catch (Exception e) {
Slog.w(TAG_WM, "Exception when removing starting window", e);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 899266d..680937b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4159,21 +4159,21 @@
/**
* Update the asset configuration and increase the assets sequence number.
- * @param processes the processes that needs to update the asset configuration, if none
- * updates the global configuration for all processes.
+ * @param processes the processes that needs to update the asset configuration
*/
- public void updateAssetConfiguration(List<WindowProcessController> processes) {
+ public void updateAssetConfiguration(List<WindowProcessController> processes,
+ boolean updateFrameworkRes) {
synchronized (mGlobalLock) {
final int assetSeq = increaseAssetConfigurationSeq();
- // Update the global configuration if the no target processes
- if (processes == null) {
+ if (updateFrameworkRes) {
Configuration newConfig = new Configuration();
newConfig.assetsSeq = assetSeq;
updateConfiguration(newConfig);
- return;
}
+ // Always update the override of every process so the asset sequence of the process is
+ // always greater than or equal to the global configuration.
for (int i = processes.size() - 1; i >= 0; i--) {
final WindowProcessController wpc = processes.get(i);
wpc.updateAssetConfiguration(assetSeq);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index c674cb85..18ea738b 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -316,7 +316,7 @@
final int myPid = Process.myPid();
final IBinder clientToken = touchedWin.mClient.asBinder();
final DragEvent event = obtainDragEvent(DragEvent.ACTION_DROP, x, y,
- true /* includeData */, targetInterceptsGlobalDrag(touchedWin),
+ mData, targetInterceptsGlobalDrag(touchedWin),
dragAndDropPermissions);
try {
touchedWin.mClient.dispatchDragEvent(event);
@@ -462,8 +462,10 @@
boolean containsAppExtras) {
final boolean interceptsGlobalDrag = targetInterceptsGlobalDrag(newWin);
if (mDragInProgress && isValidDropTarget(newWin, containsAppExtras, interceptsGlobalDrag)) {
+ // Only allow the extras to be dispatched to a global-intercepting drag target
+ ClipData data = interceptsGlobalDrag ? mData.copyForTransferWithActivityInfo() : null;
DragEvent event = obtainDragEvent(DragEvent.ACTION_DRAG_STARTED, touchX, touchY,
- interceptsGlobalDrag, false /* includeDragSurface */,
+ data, false /* includeDragSurface */,
null /* dragAndDropPermission */);
try {
newWin.mClient.dispatchDragEvent(event);
@@ -614,11 +616,11 @@
return mDragInProgress;
}
- private DragEvent obtainDragEvent(int action, float x, float y, boolean includeData,
+ private DragEvent obtainDragEvent(int action, float x, float y, ClipData data,
boolean includeDragSurface, IDragAndDropPermissions dragAndDropPermissions) {
return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY,
- null /* localState */, mDataDescription,
- includeData ? mData : null, includeDragSurface ? mSurfaceControl : null,
+ null /* localState */, mDataDescription, data,
+ includeDragSurface ? mSurfaceControl : null,
dragAndDropPermissions, false /* result */);
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 9d8b8f7..58363f2 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -212,6 +212,7 @@
String name = "RotationLayer";
mScreenshotLayer = displayContent.makeOverlay()
.setName(name)
+ .setOpaque(true)
.setSecure(isSecure)
.setCallsite("ScreenRotationAnimation")
.setBLASTLayer()
diff --git a/services/core/java/com/android/server/wm/SnapshotStartingData.java b/services/core/java/com/android/server/wm/SnapshotStartingData.java
index 66ae0eb..b6cf91a 100644
--- a/services/core/java/com/android/server/wm/SnapshotStartingData.java
+++ b/services/core/java/com/android/server/wm/SnapshotStartingData.java
@@ -41,6 +41,11 @@
}
@Override
+ boolean needRevealAnimation() {
+ return false;
+ }
+
+ @Override
boolean hasImeSurface() {
return mSnapshot.hasImeSurface();
}
diff --git a/services/core/java/com/android/server/wm/SplashScreenStartingData.java b/services/core/java/com/android/server/wm/SplashScreenStartingData.java
index 185a317..c659c05 100644
--- a/services/core/java/com/android/server/wm/SplashScreenStartingData.java
+++ b/services/core/java/com/android/server/wm/SplashScreenStartingData.java
@@ -58,4 +58,9 @@
mLogo, mWindowFlags, mMergedOverrideConfiguration,
activity.getDisplayContent().getDisplayId());
}
+
+ @Override
+ boolean needRevealAnimation() {
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java
index 3f9c93b..c671e38 100644
--- a/services/core/java/com/android/server/wm/StartingData.java
+++ b/services/core/java/com/android/server/wm/StartingData.java
@@ -47,6 +47,11 @@
*/
abstract StartingSurface createStartingSurface(ActivityRecord activity);
+ /**
+ * @return Whether to apply reveal animation when exiting the starting window.
+ */
+ abstract boolean needRevealAnimation();
+
/** @see android.window.TaskSnapshot#hasImeSurface() */
boolean hasImeSurface() {
return false;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 3a2ca80..abcb34c 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -197,6 +197,7 @@
ANIMATION_TYPE_STARTING_REVEAL);
windowAnimationLeash = adaptor.mAnimationLeash;
mainFrame = mainWindow.getRelativeFrame();
+ t.setPosition(windowAnimationLeash, mainFrame.left, mainFrame.top);
}
}
}
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index 5e81e40..4007661 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -133,7 +133,7 @@
Slog.d(TAG, "App relayouted appWindow=" + activity);
}
int state = mUnknownApps.get(activity);
- if (state == UNKNOWN_STATE_WAITING_RELAYOUT) {
+ if (state == UNKNOWN_STATE_WAITING_RELAYOUT || activity.mStartingWindow != null) {
mUnknownApps.put(activity, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
mService.notifyKeyguardFlagsChanged(this::notifyVisibilitiesUpdated,
activity.getDisplayContent().getDisplayId());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index ce8f6df..37a84f3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -104,8 +104,6 @@
private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length";
private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length";
private static final String TAG_PASSWORD_QUALITY = "password-quality";
- private static final String TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT =
- "password-quality-applies-parent";
private static final String TAG_POLICIES = "policies";
private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
"cross-profile-widget-providers";
@@ -158,7 +156,6 @@
@NonNull
PasswordPolicy mPasswordPolicy = new PasswordPolicy();
- boolean mPasswordPolicyAppliesToParent = true;
@DevicePolicyManager.PasswordComplexity
int mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
@@ -363,9 +360,6 @@
writeAttributeValueToXml(
out, TAG_MIN_PASSWORD_NONLETTER, mPasswordPolicy.nonLetter);
}
-
- writeAttributeValueToXml(out, TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT,
- mPasswordPolicyAppliesToParent);
}
if (passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
writeAttributeValueToXml(
@@ -669,8 +663,6 @@
mPasswordPolicy.symbols = parser.getAttributeInt(null, ATTR_VALUE);
} else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
mPasswordPolicy.nonLetter = parser.getAttributeInt(null, ATTR_VALUE);
- } else if (TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT.equals(tag)) {
- mPasswordPolicyAppliesToParent = parser.getAttributeBoolean(null, ATTR_VALUE);
} else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
maximumTimeToUnlock = parser.getAttributeLong(null, ATTR_VALUE);
} else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
@@ -1036,9 +1028,6 @@
pw.print("minimumPasswordNonLetter=");
pw.println(mPasswordPolicy.nonLetter);
- pw.print("passwordPolicyAppliesToParent=");
- pw.println(mPasswordPolicyAppliesToParent);
-
pw.print("maximumTimeToUnlock=");
pw.println(maximumTimeToUnlock);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 78ad59f..2bacc44 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3827,10 +3827,9 @@
isProfileOwner(caller) || isDeviceOwner(caller) || isSystemUid(caller)
|| isPasswordLimitingAdminTargetingP(caller));
- final boolean qualityMayApplyToParent =
- canSetPasswordQualityOnParent(who.getPackageName(), caller);
- if (!qualityMayApplyToParent) {
- Preconditions.checkCallAuthorization(!parent,
+ if (parent) {
+ Preconditions.checkCallAuthorization(
+ canSetPasswordQualityOnParent(who.getPackageName(), caller),
"Profile Owner may not apply password quality requirements device-wide");
}
@@ -3856,7 +3855,6 @@
if (passwordPolicy.quality != quality) {
passwordPolicy.quality = quality;
ap.mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
- ap.mPasswordPolicyAppliesToParent = qualityMayApplyToParent;
resetInactivePasswordRequirementsIfRPlus(userId, ap);
updatePasswordValidityCheckpointLocked(userId, parent);
updatePasswordQualityCacheForUserGroup(userId);
@@ -4588,8 +4586,8 @@
}
ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>();
+ final List<ActiveAdmin> admins;
synchronized (getLockObject()) {
- final List<ActiveAdmin> admins;
if (deviceWideOnly) {
admins = getActiveAdminsForUserAndItsManagedProfilesLocked(userId,
/* shouldIncludeProfileAdmins */ (user) -> false);
@@ -4597,16 +4595,7 @@
admins = getActiveAdminsForLockscreenPoliciesLocked(userId);
}
for (ActiveAdmin admin : admins) {
- final boolean isAdminOfUser = userId == admin.getUserHandle().getIdentifier();
- // Use the password metrics from the admin in one of three cases:
- // (1) The admin is of the user we're getting the minimum metrics for. The admin
- // always affects the user it's managing. This applies also to the parent
- // ActiveAdmin instance: It'd have the same user handle.
- // (2) The mPasswordPolicyAppliesToParent field is true: That indicates the
- // call to setPasswordQuality was made by an admin that may affect the parent.
- if (isAdminOfUser || admin.mPasswordPolicyAppliesToParent) {
- adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
- }
+ adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
}
}
return PasswordMetrics.merge(adminMetrics);
@@ -4821,7 +4810,6 @@
admin.mPasswordComplexity = passwordComplexity;
// Reset the password policy.
admin.mPasswordPolicy = new PasswordPolicy();
- admin.mPasswordPolicyAppliesToParent = true;
updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent);
updatePasswordQualityCacheForUserGroup(caller.getUserId());
saveSettingsLocked(caller.getUserId());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index a71b481..d4908ee 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -16,6 +16,7 @@
package com.android.server.accessibility;
+import static android.view.KeyCharacterMap.VIRTUAL_KEYBOARD;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_HOVER_MOVE;
import static android.view.MotionEvent.ACTION_UP;
@@ -112,6 +113,13 @@
private static final int CONTINUED_LINE_SEQUENCE_1 = 52;
private static final int CONTINUED_LINE_SEQUENCE_2 = 53;
+ private static final float PRESSURE = 1;
+ private static final float X_PRECISION = 1;
+ private static final float Y_PRECISION = 1;
+ private static final int EDGEFLAGS = 0;
+ private static final float POINTER_SIZE = 1;
+ private static final int METASTATE = 0;
+
MotionEventInjector mMotionEventInjector;
IAccessibilityServiceClient mServiceInterface;
List<GestureStep> mLineList = new ArrayList<>();
@@ -152,14 +160,18 @@
CONTINUED_LINE_STROKE_ID_1, false, CONTINUED_LINE_INTERVAL, CONTINUED_LINE_MID1,
CONTINUED_LINE_MID2, CONTINUED_LINE_END);
- mClickDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, CLICK_POINT.x, CLICK_POINT.y, 0);
+ mClickDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, CLICK_POINT.x, CLICK_POINT.y,
+ PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION, VIRTUAL_KEYBOARD,
+ EDGEFLAGS);
mClickDownEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
mClickUpEvent = MotionEvent.obtain(0, CLICK_DURATION, ACTION_UP, CLICK_POINT.x,
- CLICK_POINT.y, 0);
+ CLICK_POINT.y, PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION,
+ VIRTUAL_KEYBOARD, EDGEFLAGS);
mClickUpEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
mHoverMoveEvent = MotionEvent.obtain(0, 0, ACTION_HOVER_MOVE, CLICK_POINT.x, CLICK_POINT.y,
- 0);
+ PRESSURE, POINTER_SIZE, METASTATE, X_PRECISION, Y_PRECISION, VIRTUAL_KEYBOARD,
+ EDGEFLAGS);
mHoverMoveEvent.setSource(InputDevice.SOURCE_MOUSE);
mIsLineStart = allOf(IS_ACTION_DOWN, isAtPoint(LINE_START), hasStandardInitialization(),
@@ -874,12 +886,14 @@
return new TypeSafeMatcher<MotionEvent>() {
@Override
protected boolean matchesSafely(MotionEvent event) {
- return (0 == event.getActionIndex()) && (0 == event.getDeviceId())
- && (0 == event.getEdgeFlags()) && (0 == event.getFlags())
- && (0 == event.getMetaState()) && (0F == event.getOrientation())
+ return (0 == event.getActionIndex()) && (VIRTUAL_KEYBOARD == event.getDeviceId())
+ && (EDGEFLAGS == event.getEdgeFlags()) && (0 == event.getFlags())
+ && (METASTATE == event.getMetaState()) && (0F == event.getOrientation())
&& (0F == event.getTouchMajor()) && (0F == event.getTouchMinor())
- && (1F == event.getXPrecision()) && (1F == event.getYPrecision())
- && (1 == event.getPointerCount()) && (1F == event.getPressure())
+ && (X_PRECISION == event.getXPrecision())
+ && (Y_PRECISION == event.getYPrecision())
+ && (POINTER_SIZE == event.getSize())
+ && (1 == event.getPointerCount()) && (PRESSURE == event.getPressure())
&& (InputDevice.SOURCE_TOUCHSCREEN == event.getSource());
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index 4b030d1..b580eae 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -35,6 +35,7 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Handler;
@@ -43,7 +44,9 @@
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.os.Parcel;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
@@ -53,6 +56,7 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
@@ -62,11 +66,13 @@
import org.junit.Test;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
/**
* Tests for {@link ActivityManager}.
@@ -94,6 +100,20 @@
"com.android.servicestests.apps.simpleservicetestapp.ACTION_FGS_STATS_TEST";
private static final String EXTRA_MESSENGER = "extra_messenger";
+ private static final String EXTRA_CALLBACK = "callback";
+ private static final String EXTRA_COMMAND = "command";
+ private static final String EXTRA_FLAGS = "flags";
+ private static final String EXTRA_TARGET_PACKAGE = "target_package";
+
+ private static final int COMMAND_INVALID = 0;
+ private static final int COMMAND_EMPTY = 1;
+ private static final int COMMAND_BIND_SERVICE = 2;
+ private static final int COMMAND_UNBIND_SERVICE = 3;
+ private static final int COMMAND_STOP_SELF = 4;
+
+ private static final String TEST_ISOLATED_CLASS =
+ "com.android.servicestests.apps.simpleservicetestapp.SimpleIsolatedService";
+
private IActivityManager mService;
private IRemoteCallback mCallback;
private Context mContext;
@@ -333,6 +353,12 @@
SettingsSession<String> amConstantsSettings = null;
DeviceConfigSession<Long> freezerDebounceTimeout = null;
MyServiceConnection autoConnection = null;
+ final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ final PackageManager pm = mContext.getPackageManager();
+ final int uid1 = pm.getPackageUid(TEST_APP1, 0);
+ final int uid2 = pm.getPackageUid(TEST_APP2, 0);
+ final MyUidImportanceListener uid1Listener = new MyUidImportanceListener(uid1);
+ final MyUidImportanceListener uid2Listener = new MyUidImportanceListener(uid2);
try {
if (!freezerWasEnabled) {
freezerEnabled = new SettingsSession<>(
@@ -346,7 +372,7 @@
}
}
freezerDebounceTimeout = new DeviceConfigSession<>(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
CachedAppOptimizer.KEY_FREEZER_DEBOUNCE_TIMEOUT,
DeviceConfig::getLong, CachedAppOptimizer.DEFAULT_FREEZER_DEBOUNCE_TIMEOUT);
freezerDebounceTimeout.set(waitFor);
@@ -359,13 +385,20 @@
amConstantsSettings.set(
ActivityManagerConstants.KEY_MAX_SERVICE_INACTIVITY + "=" + waitFor);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP1);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP2);
+
+ am.addOnUidImportanceListener(uid1Listener,
+ RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE);
+ am.addOnUidImportanceListener(uid2Listener, RunningAppProcessInfo.IMPORTANCE_CACHED);
+
final Intent intent = new Intent();
intent.setClassName(TEST_APP1, TEST_CLASS);
- final CountDownLatch latch = new CountDownLatch(1);
+ CountDownLatch latch = new CountDownLatch(1);
autoConnection = new MyServiceConnection(latch);
mContext.bindService(intent, autoConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT);
+ Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY);
try {
assertTrue("Timeout to bind to service " + intent.getComponent(),
latch.await(AWAIT_TIMEOUT, TimeUnit.MILLISECONDS));
@@ -383,6 +416,37 @@
// It still shouldn't be frozen, although it's been in cached state.
assertFalse(TEST_APP1 + " shouldn't be frozen now.", isAppFrozen(TEST_APP1));
+
+ final CountDownLatch[] latchHolder = new CountDownLatch[1];
+ final IRemoteCallback callback = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle bundle) {
+ if (bundle != null) {
+ latchHolder[0].countDown();
+ }
+ }
+ };
+
+ // Bind from app1 to app2 without BIND_WAIVE_PRIORITY.
+ final Bundle extras = new Bundle();
+ extras.putBinder(EXTRA_CALLBACK, callback.asBinder());
+ latchHolder[0] = new CountDownLatch(1);
+ sendCommand(COMMAND_BIND_SERVICE, TEST_APP1, TEST_APP2, extras);
+ assertTrue("Timed out to bind to " + TEST_APP2, latchHolder[0].await(
+ waitFor, TimeUnit.MILLISECONDS));
+
+ // Stop service in app1
+ extras.clear();
+ sendCommand(COMMAND_STOP_SELF, TEST_APP1, TEST_APP1, extras);
+
+ assertTrue(TEST_APP2 + " should be in cached", uid2Listener.waitFor(
+ RunningAppProcessInfo.IMPORTANCE_CACHED, waitFor));
+
+ // Wait for the freezer kick in if there is any.
+ Thread.sleep(waitFor * 4);
+
+ // It still shouldn't be frozen, although it's been in cached state.
+ assertFalse(TEST_APP2 + " shouldn't be frozen now.", isAppFrozen(TEST_APP2));
} finally {
toggleScreenOn(true);
if (amConstantsSettings != null) {
@@ -397,9 +461,26 @@
if (autoConnection != null) {
mContext.unbindService(autoConnection);
}
+ am.removeOnUidImportanceListener(uid1Listener);
+ am.removeOnUidImportanceListener(uid2Listener);
+ sendCommand(COMMAND_UNBIND_SERVICE, TEST_APP1, TEST_APP2, null);
+ sendCommand(COMMAND_UNBIND_SERVICE, TEST_APP2, TEST_APP1, null);
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP1);
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP2);
}
}
+ private void sendCommand(int command, String sourcePkg, String targetPkg, Bundle extras) {
+ final Intent intent = new Intent();
+ intent.setClassName(sourcePkg, TEST_CLASS);
+ intent.putExtra(EXTRA_COMMAND, command);
+ intent.putExtra(EXTRA_TARGET_PACKAGE, targetPkg);
+ if (extras != null) {
+ intent.putExtras(extras);
+ }
+ mContext.startService(intent);
+ }
+
private boolean isFreezerEnabled() throws Exception {
final String output = runShellCommand("dumpsys activity settings");
final Matcher matcher = Pattern.compile("\\b" + CachedAppOptimizer.KEY_USE_FREEZER
@@ -496,6 +577,127 @@
return -1;
}
+ @Test
+ public void testGetIsolatedProcesses() throws Exception {
+ final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ final PackageManager pm = mContext.getPackageManager();
+ final int uid1 = pm.getPackageUid(TEST_APP1, 0);
+ final int uid2 = pm.getPackageUid(TEST_APP2, 0);
+ final int uid3 = pm.getPackageUid(TEST_APP3, 0);
+ final List<Pair<Integer, ServiceConnection>> uid1Processes = new ArrayList<>();
+ final List<Pair<Integer, ServiceConnection>> uid2Processes = new ArrayList<>();
+ try {
+ assertTrue("There shouldn't be any isolated process for " + TEST_APP1,
+ getIsolatedProcesses(uid1).isEmpty());
+ assertTrue("There shouldn't be any isolated process for " + TEST_APP2,
+ getIsolatedProcesses(uid2).isEmpty());
+ assertTrue("There shouldn't be any isolated process for " + TEST_APP3,
+ getIsolatedProcesses(uid3).isEmpty());
+
+ // Verify uid1
+ uid1Processes.add(createIsolatedProcessAndVerify(TEST_APP1, uid1));
+ uid1Processes.add(createIsolatedProcessAndVerify(TEST_APP1, uid1));
+ uid1Processes.add(createIsolatedProcessAndVerify(TEST_APP1, uid1));
+ verifyIsolatedProcesses(uid1Processes, getIsolatedProcesses(uid1));
+
+ // Let one of the processes go
+ final Pair<Integer, ServiceConnection> uid1P2 = uid1Processes.remove(2);
+ mContext.unbindService(uid1P2.second);
+ Thread.sleep(5_000); // Wait for the process gone.
+ verifyIsolatedProcesses(uid1Processes, getIsolatedProcesses(uid1));
+
+ // Verify uid2
+ uid2Processes.add(createIsolatedProcessAndVerify(TEST_APP2, uid2));
+ verifyIsolatedProcesses(uid2Processes, getIsolatedProcesses(uid2));
+
+ // Verify uid1 again
+ verifyIsolatedProcesses(uid1Processes, getIsolatedProcesses(uid1));
+
+ // Verify uid3
+ assertTrue("There shouldn't be any isolated process for " + TEST_APP3,
+ getIsolatedProcesses(uid3).isEmpty());
+ } finally {
+ for (Pair<Integer, ServiceConnection> p: uid1Processes) {
+ mContext.unbindService(p.second);
+ }
+ for (Pair<Integer, ServiceConnection> p: uid2Processes) {
+ mContext.unbindService(p.second);
+ }
+ am.forceStopPackage(TEST_APP1);
+ am.forceStopPackage(TEST_APP2);
+ am.forceStopPackage(TEST_APP3);
+ }
+ }
+
+ private static List<Integer> getIsolatedProcesses(int uid) throws Exception {
+ final String output = runShellCommand("am get-isolated-pids " + uid);
+ final Matcher matcher = Pattern.compile("(\\d+)").matcher(output);
+ final List<Integer> pids = new ArrayList<>();
+ while (matcher.find()) {
+ pids.add(Integer.parseInt(output.substring(matcher.start(), matcher.end())));
+ }
+ return pids;
+ }
+
+ private void verifyIsolatedProcesses(List<Pair<Integer, ServiceConnection>> processes,
+ List<Integer> pids) {
+ final List<Integer> l = processes.stream().map(p -> p.first).collect(Collectors.toList());
+ assertTrue("Isolated processes don't match", l.containsAll(pids));
+ assertTrue("Isolated processes don't match", pids.containsAll(l));
+ }
+
+ private Pair<Integer, ServiceConnection> createIsolatedProcessAndVerify(String pkgName, int uid)
+ throws Exception {
+ final Pair<Integer, ServiceConnection> p = createIsolatedProcess(pkgName);
+ final List<Integer> pids = getIsolatedProcesses(uid);
+ assertTrue("Can't find the isolated pid " + p.first + " for " + pkgName,
+ pids.contains(p.first));
+ return p;
+ }
+
+ private Pair<Integer, ServiceConnection> createIsolatedProcess(String pkgName)
+ throws Exception {
+ final int[] pid = new int[1];
+ final CountDownLatch[] latch = new CountDownLatch[1];
+ final ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ final IRemoteCallback s = IRemoteCallback.Stub.asInterface(service);
+ final IBinder callback = new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ if (code == Binder.FIRST_CALL_TRANSACTION) {
+ pid[0] = data.readInt();
+ latch[0].countDown();
+ return true;
+ }
+ return super.onTransact(code, data, reply, flags);
+ }
+ };
+ try {
+ final Bundle extra = new Bundle();
+ extra.putBinder(EXTRA_CALLBACK, callback);
+ s.sendResult(extra);
+ } catch (RemoteException e) {
+ fail("Unable to call into isolated process");
+ }
+ }
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+ final Intent intent = new Intent();
+ intent.setClassName(pkgName, TEST_ISOLATED_CLASS);
+ latch[0] = new CountDownLatch(1);
+ assertTrue("Unable to create isolated process in " + pkgName,
+ mContext.bindIsolatedService(intent, Context.BIND_AUTO_CREATE,
+ Long.toString(SystemClock.uptimeMillis()), mContext.getMainExecutor(), conn));
+ assertTrue("Timeout to bind to service " + intent.getComponent(),
+ latch[0].await(AWAIT_TIMEOUT, TimeUnit.MILLISECONDS));
+ return Pair.create(pid[0], conn);
+ }
+
/**
* Make sure the screen state.
*/
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index cedf636..7b20bf0 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5428,6 +5428,205 @@
}
@Test
+ public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileQualityRequirementMet()
+ throws Exception {
+ // Create work profile with empty separate challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ true);
+
+ // Set profile password quality requirement. No password added yet so
+ // profile.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+
+ // Set a work challenge and verify profile.isActivePasswordSufficient is now true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId))
+ .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileComplexityRequirementMet()
+ throws Exception {
+ // Create work profile with empty separate challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ true);
+
+ // Set profile password complexity requirement. No password added yet so
+ // profile.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+
+ // Set a work challenge and verify profile.isActivePasswordSufficient is now true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId))
+ .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_SeparateWorkChallenge_ParentQualityRequirementMet()
+ throws Exception {
+ // Create work profile with empty separate challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ true);
+
+ // Set parent password quality requirement. No password added yet so
+ // parent.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_SeparateWorkChallenge_ParentComplexityRequirementMet()
+ throws Exception {
+ // Create work profile with empty separate challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ true);
+
+ // Set parent password complexity requirement. No password added yet so
+ // parent.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileQualityRequirementMet()
+ throws Exception {
+ // Create work profile with unified challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ false);
+
+ // Set profile password quality requirement. No password added yet so
+ // {profile, parent}.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileComplexityRequirementMet()
+ throws Exception {
+ // Create work profile with unified challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ false);
+
+ // Set profile password complexity requirement. No password added yet so
+ // {profile, parent}.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentQualityRequirementMet()
+ throws Exception {
+ // Create work profile with unified challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ false);
+
+ // Set parent password quality requirement. No password added yet so
+ // {profile, parent}.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ @Test
+ public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentComplexityRequirementMet()
+ throws Exception {
+ // Create work profile with unified challenge
+ final int managedProfileUserId = 15;
+ final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+ addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid,
+ /* separateChallenge */ false);
+
+ // Set parent password complexity requirement. No password added yet so
+ // {profile, parent}.isActivePasswordSufficient should return false
+ mContext.binder.callingUid = managedProfileAdminUid;
+ parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
+ assertThat(dpm.isActivePasswordSufficient()).isFalse();
+ assertThat(parentDpm.isActivePasswordSufficient()).isFalse();
+
+ // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true));
+ assertThat(dpm.isActivePasswordSufficient()).isTrue();
+ assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
+ }
+
+ private void addManagedProfileForPasswordTests(int userId, int adminUid,
+ boolean separateChallenge) throws Exception {
+ addManagedProfile(admin1, adminUid, admin1);
+ when(getServices().userManager.getProfileParent(userId))
+ .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
+ doReturn(separateChallenge).when(getServices().lockPatternUtils)
+ .isSeparateProfileChallengeEnabled(userId);
+ when(getServices().userManager.getCredentialOwnerProfile(userId))
+ .thenReturn(separateChallenge ? userId : UserHandle.USER_SYSTEM);
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(userId))
+ .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE));
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
+ .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE));
+ }
+
+ @Test
public void testPasswordQualityAppliesToParentPreS() throws Exception {
final int managedProfileUserId = CALLER_USER_HANDLE;
final int managedProfileAdminUid =
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/SimpleServiceTestApp/AndroidManifest.xml
index 799ec53..78afb7b 100644
--- a/services/tests/servicestests/test-apps/SimpleServiceTestApp/AndroidManifest.xml
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/AndroidManifest.xml
@@ -24,6 +24,9 @@
android:exported="true" />
<service android:name=".SimpleFgService"
android:exported="true" />
+ <service android:name=".SimpleIsolatedService"
+ android:isolatedProcess="true"
+ android:exported="true" />
</application>
</manifest>
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleIsolatedService.java b/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleIsolatedService.java
new file mode 100644
index 0000000..8b281c1
--- /dev/null
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleIsolatedService.java
@@ -0,0 +1,56 @@
+/*
+ * 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.servicestests.apps.simpleservicetestapp;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IRemoteCallback;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class SimpleIsolatedService extends Service {
+ private static final String TAG = "SimpleIsolatedService";
+ private static final String EXTRA_CALLBACK = "callback";
+
+ private final IRemoteCallback.Stub mBinder = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle bundle) {
+ final IBinder callback = bundle.getBinder(EXTRA_CALLBACK);
+ final Parcel data = Parcel.obtain();
+ final Parcel reply = Parcel.obtain();
+ try {
+ data.writeInt(Process.myPid());
+ callback.transact(Binder.FIRST_CALL_TRANSACTION, data, reply, 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception", e);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i(TAG, "onBind");
+ return mBinder;
+ }
+}
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleService.java b/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleService.java
index 674ce8a..4e981b2 100644
--- a/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleService.java
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/src/com/android/servicestests/apps/simpleservicetestapp/SimpleService.java
@@ -16,29 +16,106 @@
package com.android.servicestests.apps.simpleservicetestapp;
import android.app.Service;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Process;
+import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.Log;
public class SimpleService extends Service {
private static final String TAG = "SimpleService";
+ private static final String TEST_CLASS =
+ "com.android.servicestests.apps.simpleservicetestapp.SimpleService";
+
+ private static final String EXTRA_CALLBACK = "callback";
+ private static final String EXTRA_COMMAND = "command";
+ private static final String EXTRA_FLAGS = "flags";
+ private static final String EXTRA_TARGET_PACKAGE = "target_package";
+
+ private static final int COMMAND_INVALID = 0;
+ private static final int COMMAND_EMPTY = 1;
+ private static final int COMMAND_BIND_SERVICE = 2;
+ private static final int COMMAND_UNBIND_SERVICE = 3;
+ private static final int COMMAND_STOP_SELF = 4;
+
+ private ArrayMap<String, ServiceConnection> mServiceConnections = new ArrayMap<>();
+
private final IRemoteCallback.Stub mBinder = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle bundle) {
- Process.killProcess(Process.myPid());
+ if (bundle == null) {
+ Process.killProcess(Process.myPid());
+ } else {
+ // No-op for now.
+ }
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
+ int command = intent.getIntExtra(EXTRA_COMMAND, COMMAND_INVALID);
+ if (command != COMMAND_INVALID) {
+ final String targetPkg = intent.getStringExtra(EXTRA_TARGET_PACKAGE);
+ Log.i(TAG, "Received command " + command + " targetPkg=" + targetPkg);
+ switch (command) {
+ case COMMAND_BIND_SERVICE:
+ final Bundle extras = intent.getExtras();
+ bindToService(targetPkg, intent.getIntExtra(EXTRA_FLAGS, 0),
+ IRemoteCallback.Stub.asInterface(extras.getBinder(EXTRA_CALLBACK)));
+ break;
+ case COMMAND_UNBIND_SERVICE:
+ unbindService(targetPkg);
+ break;
+ case COMMAND_STOP_SELF:
+ stopSelf();
+ return START_NOT_STICKY;
+ }
+ }
return START_STICKY;
}
+ private void bindToService(String targetPkg, int flags, IRemoteCallback callback) {
+ Intent intent = new Intent();
+ intent.setClassName(targetPkg, TEST_CLASS);
+ final ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (callback != null) {
+ try {
+ callback.sendResult(new Bundle());
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+ if (getApplicationContext().bindService(intent, conn, BIND_AUTO_CREATE | flags)) {
+ mServiceConnections.put(targetPkg, conn);
+ } else if (callback != null) {
+ try {
+ callback.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private void unbindService(String targetPkg) {
+ final ServiceConnection conn = mServiceConnections.remove(targetPkg);
+ if (conn != null) {
+ getApplicationContext().unbindService(conn);
+ }
+ }
+
@Override
public IBinder onBind(Intent intent) {
return mBinder;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 3c6f62a..f57c416 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -4855,6 +4855,9 @@
@Test
public void testAreBubblesEnabled() throws Exception {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BUBBLES, 1);
+ mService.mPreferencesHelper.updateBubblesEnabled();
assertTrue(mBinderService.areBubblesEnabled(UserHandle.getUserHandleForUid(mUid)));
}
@@ -5907,7 +5910,8 @@
service.migrateDefaultNASShowNotificationIfNecessary();
assertFalse(service.isNASMigrationDone(userId));
- verify(service, times(1)).createNASUpgradeNotification(eq(userId));
+ //TODO(b/192450820)
+ //verify(service, times(1)).createNASUpgradeNotification(eq(userId));
verify(mAssistants, times(0)).resetDefaultFromConfig();
//Test user clear data before enable/disable from onboarding notification
@@ -5926,7 +5930,8 @@
//The notification should be still there
assertFalse(service.isNASMigrationDone(userId));
- verify(service, times(2)).createNASUpgradeNotification(eq(userId));
+ //TODO(b/192450820)
+ //verify(service, times(2)).createNASUpgradeNotification(eq(userId));
verify(mAssistants, times(0)).resetDefaultFromConfig();
assertEquals(oldDefaultComponent, service.getApprovedAssistant(userId));
}
@@ -5962,7 +5967,8 @@
assertFalse(service.isNASMigrationDone(userId1));
assertTrue(service.isNASMigrationDone(userId2));
- verify(service, times(1)).createNASUpgradeNotification(any(Integer.class));
+ //TODO(b/192450820)
+ //verify(service, times(1)).createNASUpgradeNotification(any(Integer.class));
// only user2's default get updated
verify(mAssistants, times(1)).resetDefaultFromConfig();
}
@@ -5997,9 +6003,9 @@
assertFalse(service.isNASMigrationDone(userId1));
assertFalse(service.isNASMigrationDone(userId2));
- // only user1 get notification
- verify(service, times(1)).createNASUpgradeNotification(eq(userId1));
- verify(service, times(0)).createNASUpgradeNotification(eq(userId2));
+ // TODO(b/192450820): only user1 get notification
+ //verify(service, times(1)).createNASUpgradeNotification(eq(userId1));
+ //verify(service, times(0)).createNASUpgradeNotification(eq(userId2));
}
@@ -6029,8 +6035,8 @@
//Test migrate flow again
service.migrateDefaultNASShowNotificationIfNecessary();
- //The notification should not appear again
- verify(service, times(0)).createNASUpgradeNotification(eq(userId));
+ //TODO(b/192450820): The notification should not appear again
+ //verify(service, times(0)).createNASUpgradeNotification(eq(userId));
verify(mAssistants, times(0)).resetDefaultFromConfig();
}
@@ -6055,9 +6061,9 @@
verify(mAssistants, times(1)).clearDefaults();
verify(mAssistants, times(0)).resetDefaultFromConfig();
- //No more notification after disabled
- service.migrateDefaultNASShowNotificationIfNecessary();
- verify(service, times(0)).createNASUpgradeNotification(anyInt());
+ //TODO(b/192450820):No more notification after disabled
+ //service.migrateDefaultNASShowNotificationIfNecessary();
+ //verify(service, times(0)).createNASUpgradeNotification(anyInt());
}
@Test
@@ -6077,8 +6083,9 @@
assertFalse(service.isNASMigrationDone(userId2));
verify(mAssistants, times(1)).resetDefaultFromConfig();
- service.migrateDefaultNASShowNotificationIfNecessary();
- verify(service, times(0)).createNASUpgradeNotification(eq(userId1));
+ //TODO(b/192450820)
+ //service.migrateDefaultNASShowNotificationIfNecessary();
+ //verify(service, times(0)).createNASUpgradeNotification(eq(userId1));
}
@Test
@@ -6093,7 +6100,8 @@
verify(mContext, times(1)).startActivity(any(Intent.class));
assertFalse(service.isNASMigrationDone(userId));
- verify(service, times(0)).createNASUpgradeNotification(eq(userId));
+ //TODO(b/192450820)
+ //verify(service, times(0)).createNASUpgradeNotification(eq(userId));
verify(mAssistants, times(0)).resetDefaultFromConfig();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 8981ab1..223dc31 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -22,6 +22,7 @@
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.DragEvent.ACTION_DRAG_STARTED;
+import static android.view.DragEvent.ACTION_DROP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -31,7 +32,9 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
@@ -267,12 +270,32 @@
assertTrue(globalInterceptWindowDragEvents.get(0).getAction()
== ACTION_DRAG_STARTED);
+ // Verify that only the global intercept window receives the clip data with the
+ // resolved activity info for the drag
+ assertNull(localWindowDragEvents.get(0).getClipData());
+ assertTrue(globalInterceptWindowDragEvents.get(0).getClipData()
+ .willParcelWithActivityInfo());
+
mTarget.reportDropWindow(globalInterceptWindow.mInputChannelToken, 0, 0);
mTarget.handleMotionEvent(false, 0, 0);
mToken = globalInterceptWindow.mClient.asBinder();
+
+ // Verify the drop event is only sent for the global intercept window
+ assertTrue(nonLocalWindowDragEvents.isEmpty());
+ assertTrue(last(localWindowDragEvents).getAction() != ACTION_DROP);
+ assertTrue(last(globalInterceptWindowDragEvents).getAction() == ACTION_DROP);
+
+ // Verify that item extras were not sent with the drop event
+ assertNull(last(localWindowDragEvents).getClipData());
+ assertFalse(last(globalInterceptWindowDragEvents).getClipData()
+ .willParcelWithActivityInfo());
});
}
+ private DragEvent last(ArrayList<DragEvent> list) {
+ return list.get(list.size() - 1);
+ }
+
@Test
public void testValidateAppActivityArguments() {
final Session session = new Session(mWm, new IWindowSessionCallback.Stub() {
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerService.java b/services/translation/java/com/android/server/translation/TranslationManagerService.java
index 41ee6b5..27b254a 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerService.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerService.java
@@ -246,6 +246,16 @@
}
@Override
+ public void onTranslationFinished(boolean activityDestroyed, IBinder token,
+ ComponentName componentName, int userId) {
+ TranslationManagerServiceImpl service;
+ synchronized (mLock) {
+ service = getServiceForUserLocked(userId);
+ service.onTranslationFinishedLocked(activityDestroyed, token, componentName);
+ }
+ }
+
+ @Override
public void getServiceSettingsActivity(IResultReceiver result, int userId) {
final TranslationManagerServiceImpl service;
synchronized (mLock) {
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index 6606fb0..9f4fee8 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -20,10 +20,12 @@
import static android.view.translation.UiTranslationManager.EXTRA_SOURCE_LOCALE;
import static android.view.translation.UiTranslationManager.EXTRA_STATE;
import static android.view.translation.UiTranslationManager.EXTRA_TARGET_LOCALE;
+import static android.view.translation.UiTranslationManager.STATE_UI_TRANSLATION_FINISHED;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
@@ -33,6 +35,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.service.translation.TranslationServiceInfo;
+import android.util.ArraySet;
import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.inputmethod.InputMethodInfo;
@@ -83,6 +86,7 @@
new TranslationServiceRemoteCallback();
private final RemoteCallbackList<IRemoteCallback> mTranslationCapabilityCallbacks =
new RemoteCallbackList<>();
+ private final ArraySet<IBinder> mWaitingFinishedCallbackActivities = new ArraySet();
protected TranslationManagerServiceImpl(
@NonNull TranslationManagerService master,
@@ -169,6 +173,41 @@
}
}
+ private int getActivityUidByComponentName(Context context, ComponentName componentName,
+ int userId) {
+ int translationActivityUid = -1;
+ try {
+ if (componentName != null) {
+ translationActivityUid = context.getPackageManager().getApplicationInfoAsUser(
+ componentName.getPackageName(), 0, userId).uid;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.d(TAG, "Cannot find packageManager for" + componentName);
+ }
+ return translationActivityUid;
+ }
+
+ @GuardedBy("mLock")
+ public void onTranslationFinishedLocked(boolean activityDestroyed, IBinder token,
+ ComponentName componentName) {
+ int translationActivityUid =
+ getActivityUidByComponentName(getContext(), componentName, getUserId());
+ if (activityDestroyed) {
+ // In the Activity destroy case, we only calls onTranslationFinished() in
+ // non-finisTranslation() state. If there is a finisTranslation() calls by apps, we
+ // should remove the waiting callback to avoid callback twice.
+ invokeCallbacks(STATE_UI_TRANSLATION_FINISHED, /* sourceSpec= */
+ null, /* targetSpec= */null, translationActivityUid);
+ mWaitingFinishedCallbackActivities.remove(token);
+ } else {
+ if (mWaitingFinishedCallbackActivities.contains(token)) {
+ invokeCallbacks(STATE_UI_TRANSLATION_FINISHED, /* sourceSpec= */
+ null, /* targetSpec= */null, translationActivityUid);
+ mWaitingFinishedCallbackActivities.remove(token);
+ }
+ }
+ }
+
@GuardedBy("mLock")
public void updateUiTranslationStateLocked(@UiTranslationState int state,
TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
@@ -178,10 +217,13 @@
mActivityTaskManagerInternal.getTopActivityForTask(taskId);
if (taskTopActivityTokens == null
|| taskTopActivityTokens.getShareableActivityToken() != token) {
- Slog.w(TAG, "Unknown activity or it was finished to query for update "
- + "translation state for token=" + token + " taskId=" + taskId);
+ Slog.w(TAG, "Unknown activity or it was finished to query for update translation "
+ + "state for token=" + token + " taskId=" + taskId + " for state= " + state);
return;
}
+ if (state == STATE_UI_TRANSLATION_FINISHED) {
+ mWaitingFinishedCallbackActivities.add(token);
+ }
int translationActivityUid = -1;
try {
IBinder activityToken = taskTopActivityTokens.getActivityToken();
@@ -191,19 +233,14 @@
mLastActivityTokens = new WeakReference<>(taskTopActivityTokens);
ComponentName componentName =
mActivityTaskManagerInternal.getActivityName(activityToken);
- try {
- if (componentName != null) {
- translationActivityUid =
- getContext().getPackageManager().getApplicationInfoAsUser(
- componentName.getPackageName(), 0, getUserId()).uid;
- }
- } catch (PackageManager.NameNotFoundException e) {
- Slog.d(TAG, "Cannot find package for" + componentName);
- }
+ translationActivityUid =
+ getActivityUidByComponentName(getContext(), componentName, getUserId());
} catch (RemoteException e) {
Slog.w(TAG, "Update UiTranslationState fail: " + e);
}
- invokeCallbacks(state, sourceSpec, targetSpec, translationActivityUid);
+ if (state != STATE_UI_TRANSLATION_FINISHED) {
+ invokeCallbacks(state, sourceSpec, targetSpec, translationActivityUid);
+ }
}
@GuardedBy("mLock")
@@ -226,6 +263,14 @@
} else {
pw.print(prefix); pw.println("No requested UiTranslation Activity.");
}
+ final int waitingFinishCallbackSize = mWaitingFinishedCallbackActivities.size();
+ if (waitingFinishCallbackSize > 0) {
+ pw.print(prefix); pw.print("number waiting finish callback activities: ");
+ pw.println(waitingFinishCallbackSize);
+ for (IBinder activityToken : mWaitingFinishedCallbackActivities) {
+ pw.print(prefix); pw.print("activityToken: "); pw.println(activityToken);
+ }
+ }
}
private void invokeCallbacks(
@@ -243,7 +288,6 @@
LocalServices.getService(InputMethodManagerInternal.class)
.getEnabledInputMethodListAsUser(mUserId);
mCallbacks.broadcast((callback, uid) -> {
- // callback to the application that is translated if registered.
if ((int) uid == translationActivityUid) {
try {
callback.sendResult(res);