Merge "Construct AppsFilter cache on background thread" into rvc-qpr-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 0cadbfd..aeed188 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -455,9 +455,6 @@
mSystemServicesReady = true;
- // Offload to handler thread to avoid boot time impact.
- mHandler.post(AppStandbyController.this::updatePowerWhitelistCache);
-
boolean userFileExists;
synchronized (mAppIdleLock) {
userFileExists = mAppIdleHistory.userFileExists(UserHandle.USER_SYSTEM);
@@ -474,7 +471,9 @@
setChargingState(mInjector.isCharging());
// Offload to handler thread after boot completed to avoid boot time impact. This means
- // that headless system apps may be put in a lower bucket until boot has completed.
+ // that app standby buckets may be slightly out of date and headless system apps may be
+ // put in a lower bucket until boot has completed.
+ mHandler.post(AppStandbyController.this::updatePowerWhitelistCache);
mHandler.post(this::loadHeadlessSystemAppCache);
}
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 36b46c3..7d0d979 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -4420,15 +4420,12 @@
UNKNOWN = 0;
CHIP_VIEWED = 1;
CHIP_CLICKED = 2;
- DIALOG_PRIVACY_SETTINGS = 3;
+ reserved 3; // Used only in beta builds, never shipped
DIALOG_DISMISS = 4;
DIALOG_LINE_ITEM = 5;
}
optional Type type = 1 [(state_field_option).exclusive_state = true];
-
- // Used if the type is LINE_ITEM
- optional string package_name = 2;
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 812ca4a..8d64661 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5112,6 +5112,7 @@
}
}
r.setState(ON_DESTROY);
+ mLastReportedWindowingMode.remove(r.activity.getActivityToken());
}
schedulePurgeIdler();
// updatePendingActivityConfiguration() reads from mActivities to update
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0a6827c..eea5d62 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1124,9 +1124,32 @@
/** @hide */
public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE;
+ /**
+ * Phone call is using microphone
+ *
+ * @hide
+ */
+ // TODO: Add as AppProtoEnums
+ public static final int OP_PHONE_CALL_MICROPHONE = 100;
+ /**
+ * Phone call is using camera
+ *
+ * @hide
+ */
+ // TODO: Add as AppProtoEnums
+ public static final int OP_PHONE_CALL_CAMERA = 101;
+
+ /**
+ * Audio is being recorded for hotword detection.
+ *
+ * @hide
+ */
+ // TODO: Add as AppProtoEnums
+ public static final int OP_RECORD_AUDIO_HOTWORD = 102;
+
/** @hide */
@UnsupportedAppUsage
- public static final int _NUM_OP = 100;
+ public static final int _NUM_OP = 103;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1444,6 +1467,26 @@
*/
public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
+ /**
+ * Phone call is using microphone
+ *
+ * @hide
+ */
+ public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone";
+ /**
+ * Phone call is using camera
+ *
+ * @hide
+ */
+ public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera";
+
+ /**
+ * Audio is being recorded for hotword detection.
+ *
+ * @hide
+ */
+ public static final String OPSTR_RECORD_AUDIO_HOTWORD = "android:record_audio_hotword";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -1633,6 +1676,9 @@
OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE
+ OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE
+ OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA
+ OP_RECORD_AUDIO_HOTWORD, // RECORD_AUDIO_HOTWORD
};
/**
@@ -1739,6 +1785,9 @@
OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
OPSTR_NO_ISOLATED_STORAGE,
+ OPSTR_PHONE_CALL_MICROPHONE,
+ OPSTR_PHONE_CALL_CAMERA,
+ OPSTR_RECORD_AUDIO_HOTWORD,
};
/**
@@ -1846,6 +1895,9 @@
"AUTO_REVOKE_PERMISSIONS_IF_UNUSED",
"AUTO_REVOKE_MANAGED_BY_INSTALLER",
"NO_ISOLATED_STORAGE",
+ "PHONE_CALL_MICROPHONE",
+ "PHONE_CALL_CAMERA",
+ "RECORD_AUDIO_HOTWORD",
};
/**
@@ -1954,6 +2006,9 @@
null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // no permission for OP_NO_ISOLATED_STORAGE
+ null, // no permission for OP_PHONE_CALL_MICROPHONE
+ null, // no permission for OP_PHONE_CALL_CAMERA
+ null, // no permission for OP_RECORD_AUDIO_HOTWORD
};
/**
@@ -2062,6 +2117,9 @@
null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // NO_ISOLATED_STORAGE
+ null, // PHONE_CALL_MICROPHONE
+ null, // PHONE_CALL_MICROPHONE
+ null, // RECORD_AUDIO_HOTWORD
};
/**
@@ -2169,6 +2227,9 @@
null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // NO_ISOLATED_STORAGE
+ null, // PHONE_CALL_MICROPHONE
+ null, // PHONE_CALL_CAMERA
+ null, // RECORD_AUDIO_HOTWORD
};
/**
@@ -2275,6 +2336,9 @@
AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE
+ AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE
+ AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA
+ AppOpsManager.MODE_ALLOWED, // OP_RECORD_AUDIO_HOTWORD
};
/**
@@ -2385,6 +2449,9 @@
false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
true, // NO_ISOLATED_STORAGE
+ false, // PHONE_CALL_MICROPHONE
+ false, // PHONE_CALL_CAMERA
+ false, // RECORD_AUDIO_HOTWORD
};
/**
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 505b498..c51a846 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -187,6 +187,16 @@
private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache";
/**
+ * Special intent extra that critical system apps can use to hide the notification for a
+ * foreground service. This extra should be placed in the intent passed into {@link
+ * #startForegroundService(Intent)}.
+ *
+ * @hide
+ */
+ private static final String EXTRA_HIDDEN_FOREGROUND_SERVICE =
+ "android.intent.extra.HIDDEN_FOREGROUND_SERVICE";
+
+ /**
* Map from package name, to preference name, to cached preferences.
*/
@GuardedBy("ContextImpl.class")
@@ -1697,9 +1707,12 @@
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
+ final boolean hideForegroundNotification = requireForeground
+ && service.getBooleanExtra(EXTRA_HIDDEN_FOREGROUND_SERVICE, false);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
+ hideForegroundNotification,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
@@ -1901,10 +1914,8 @@
@Override
public Object getSystemService(String name) {
if (vmIncorrectContextUseEnabled()) {
- // We may override this API from outer context.
- final boolean isUiContext = isUiContext() || isOuterUiContext();
// Check incorrect Context usage.
- if (isUiComponent(name) && !isUiContext) {
+ if (isUiComponent(name) && !isSelfOrOuterUiContext()) {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
@@ -1921,15 +1932,17 @@
return SystemServiceRegistry.getSystemService(this, name);
}
- private boolean isOuterUiContext() {
- return getOuterContext() != null && getOuterContext().isUiContext();
- }
-
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return SystemServiceRegistry.getSystemServiceName(serviceClass);
}
+ // TODO(b/149463653): check if we still need this method after migrating IMS to WindowContext.
+ private boolean isSelfOrOuterUiContext() {
+ // We may override outer context's isUiContext
+ return isUiContext() || getOuterContext() != null && getOuterContext().isUiContext();
+ }
+
/** @hide */
@Override
public boolean isUiContext() {
@@ -2376,7 +2389,6 @@
context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
mResources.getLoaders()));
- context.mIsUiContext = isUiContext() || isOuterUiContext();
return context;
}
@@ -2396,6 +2408,11 @@
mResources.getLoaders()));
context.mDisplay = display;
context.mIsAssociatedWithDisplay = true;
+ // Note that even if a display context is derived from an UI context, it should not be
+ // treated as UI context because it does not handle configuration changes from the server
+ // side. If the context does need to handle configuration changes, please use
+ // Context#createWindowContext(int, Bundle).
+ context.mIsUiContext = false;
return context;
}
@@ -2481,9 +2498,9 @@
@Override
public Display getDisplay() {
- if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay) {
+ if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay && !isSelfOrOuterUiContext()) {
throw new UnsupportedOperationException("Tried to obtain display from a Context not "
- + "associated with one. Only visual Contexts (such as Activity or one created "
+ + "associated with one. Only visual Contexts (such as Activity or one created "
+ "with Context#createWindowContext) or ones created with "
+ "Context#createDisplayContext are associated with displays. Other types of "
+ "Contexts are typically related to background entities and may return an "
@@ -2757,6 +2774,7 @@
mDisplay = container.mDisplay;
mIsAssociatedWithDisplay = container.mIsAssociatedWithDisplay;
mIsSystemOrSystemUiContext = container.mIsSystemOrSystemUiContext;
+ mIsUiContext = container.isSelfOrOuterUiContext();
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 9459577..f98e263 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -155,7 +155,8 @@
boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta);
PendingIntent getRunningServiceControlPanel(in ComponentName service);
ComponentName startService(in IApplicationThread caller, in Intent service,
- in String resolvedType, boolean requireForeground, in String callingPackage,
+ in String resolvedType, boolean requireForeground,
+ boolean hideForegroundNotification, in String callingPackage,
in String callingFeatureId, int userId);
@UnsupportedAppUsage
int stopService(in IApplicationThread caller, in Intent service,
@@ -683,4 +684,14 @@
* Kills uid with the reason of permission change.
*/
void killUidForPermissionChange(int appId, int userId, String reason);
+
+ /**
+ * Control the app freezer state. Returns true in case of success, false if the operation
+ * didn't succeed (for example, when the app freezer isn't supported).
+ * Handling the freezer state via this method is reentrant, that is it can be
+ * disabled and re-enabled multiple times in parallel. As long as there's a 1:1 disable to
+ * enable match, the freezer is re-enabled at last enable only.
+ * @param enable set it to true to enable the app freezer, false to disable it.
+ */
+ boolean enableAppFreezer(in boolean enable);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7622688..b95a402 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5151,18 +5151,10 @@
bindHeaderChronometerAndTime(contentView, p);
bindProfileBadge(contentView, p);
bindAlertedIcon(contentView, p);
- bindActivePermissions(contentView, p);
bindExpandButton(contentView, p);
mN.mUsesStandardHeader = true;
}
- private void bindActivePermissions(RemoteViews contentView, StandardTemplateParams p) {
- int color = getNeutralColor(p);
- contentView.setDrawableTint(R.id.camera, false, color, PorterDuff.Mode.SRC_ATOP);
- contentView.setDrawableTint(R.id.mic, false, color, PorterDuff.Mode.SRC_ATOP);
- contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP);
- }
-
private void bindExpandButton(RemoteViews contentView, StandardTemplateParams p) {
int color = isColorized(p) ? getPrimaryTextColor(p) : getSecondaryTextColor(p);
contentView.setDrawableTint(R.id.expand_button, false, color,
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index f3f00e5..f99d4e9 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -176,6 +176,13 @@
*/
public boolean isResizeable;
+ /**
+ * Screen orientation set by {@link #baseActivity} via
+ * {@link Activity#setRequestedOrientation(int)}.
+ * @hide
+ */
+ public @ActivityInfo.ScreenOrientation int requestedOrientation;
+
TaskInfo() {
// Do nothing
}
@@ -247,6 +254,7 @@
? ActivityInfo.CREATOR.createFromParcel(source)
: null;
isResizeable = source.readBoolean();
+ requestedOrientation = source.readInt();
}
/**
@@ -297,6 +305,7 @@
topActivityInfo.writeToParcel(dest, flags);
}
dest.writeBoolean(isResizeable);
+ dest.writeInt(requestedOrientation);
}
@Override
@@ -315,6 +324,7 @@
+ " token=" + token
+ " topActivityType=" + topActivityType
+ " pictureInPictureParams=" + pictureInPictureParams
- + " topActivityInfo=" + topActivityInfo;
+ + " topActivityInfo=" + topActivityInfo
+ + " requestedOrientation=" + requestedOrientation;
}
}
diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java
index 7f436401..fa135b1 100644
--- a/core/java/android/app/prediction/AppPredictor.java
+++ b/core/java/android/app/prediction/AppPredictor.java
@@ -83,6 +83,8 @@
private final AppPredictionSessionId mSessionId;
private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
+ private final IBinder mToken = new Binder();
+
/**
* Creates a new Prediction client.
* <p>
@@ -98,7 +100,7 @@
mSessionId = new AppPredictionSessionId(
context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId());
try {
- mPredictionManager.createPredictionSession(predictionContext, mSessionId);
+ mPredictionManager.createPredictionSession(predictionContext, mSessionId, mToken);
} catch (RemoteException e) {
Log.e(TAG, "Failed to create predictor", e);
e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/prediction/IPredictionManager.aidl b/core/java/android/app/prediction/IPredictionManager.aidl
index 587e3fd..863fc6f9 100644
--- a/core/java/android/app/prediction/IPredictionManager.aidl
+++ b/core/java/android/app/prediction/IPredictionManager.aidl
@@ -29,7 +29,7 @@
interface IPredictionManager {
void createPredictionSession(in AppPredictionContext context,
- in AppPredictionSessionId sessionId);
+ in AppPredictionSessionId sessionId, in IBinder token);
void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index fc4ccd0..191c465 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1291,9 +1291,8 @@
*
* @throws PackageManager.NameNotFoundException if the new owner could not be found.
* @throws SecurityException if called after the session has been committed or abandoned.
- * @throws SecurityException if the session does not update the original installer
- * @throws SecurityException if streams opened through
- * {@link #openWrite(String, long, long) are still open.
+ * @throws IllegalArgumentException if streams opened through
+ * {@link #openWrite(String, long, long) are still open.
*/
public void transfer(@NonNull String packageName)
throws PackageManager.NameNotFoundException {
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index ad9bf07..8d6e937 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -260,6 +260,13 @@
int displayId, long maxFrames, long timestamp);
/**
+ * Temporarily ignore proximity-sensor-based display behavior until there is a change
+ * to the proximity sensor state. This allows the display to turn back on even if something
+ * is obstructing the proximity sensor.
+ */
+ public abstract void ignoreProximitySensorUntilChanged();
+
+ /**
* Describes the requested power state of the display.
*
* This object is intended to describe the general characteristics of the
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c5a11abe..4f0c84e 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1208,15 +1208,19 @@
mWindow.getWindow().getAttributes().setFitInsetsIgnoringVisibility(true);
// IME layout should always be inset by navigation bar, no matter its current visibility,
- // unless automotive requests it, since automotive may hide the navigation bar.
+ // unless automotive requests it. Automotive devices may request the navigation bar to be
+ // hidden when the IME shows up (controlled via config_automotiveHideNavBarForKeyboard)
+ // in order to maximize the visible screen real estate. When this happens, the IME window
+ // should animate from the bottom of the screen to reduce the jank that happens from the
+ // lack of synchronization between the bottom system window and the IME window.
+ if (mIsAutomotive && mAutomotiveHideNavBarForKeyboard) {
+ mWindow.getWindow().setDecorFitsSystemWindows(false);
+ }
mWindow.getWindow().getDecorView().setOnApplyWindowInsetsListener(
(v, insets) -> v.onApplyWindowInsets(
new WindowInsets.Builder(insets).setInsets(
navigationBars(),
- mIsAutomotive && mAutomotiveHideNavBarForKeyboard
- ? android.graphics.Insets.NONE
- : insets.getInsetsIgnoringVisibility(navigationBars())
- )
+ insets.getInsetsIgnoringVisibility(navigationBars()))
.build()));
// For ColorView in DecorView to work, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS needs to be set
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 7234eb1..cd26079 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -503,6 +503,10 @@
for (final int ratType : ratTypes) {
collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType));
}
+ // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and
+ // it is not in TelephonyManager#NETWORK_TYPE_* constants.
+ // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
+ collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA));
// Ensure that unknown type is returned.
collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN);
return toIntArray(collapsedRatTypes);
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 683993f7..0185ba4 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.util.Log;
import android.util.SparseIntArray;
@@ -255,7 +256,12 @@
// out of system_server to all processes hosting binder objects it holds a reference to;
// since some of those processes might be frozen, we don't want to block here
// forever. Disable the freezer.
- Process.enableFreezer(false);
+ try {
+ ActivityManager.getService().enableAppFreezer(false);
+ } catch (RemoteException e) {
+ Log.e(Binder.TAG, "RemoteException while disabling app freezer");
+ }
+
for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
BinderProxy bp = weakRef.get();
String key;
@@ -278,7 +284,11 @@
counts.put(key, i + 1);
}
}
- Process.enableFreezer(true);
+ try {
+ ActivityManager.getService().enableAppFreezer(true);
+ } catch (RemoteException e) {
+ Log.e(Binder.TAG, "RemoteException while re-enabling app freezer");
+ }
Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray(
new Map.Entry[counts.size()]);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b36aeb8..49a1cb58 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1006,10 +1006,16 @@
/**
* Q.
- * <p>
- * <em>Why? Why, to give you a taste of your future, a preview of things
- * to come. Con permiso, Capitan. The hall is rented, the orchestra
- * engaged. It's now time to see if you can dance.</em>
+ *
+ * <p>Applications targeting this or a later release will get these new changes in behavior.
+ * For more information about this release, see the
+ * <a href="/about/versions/10">Android 10 overview</a>.</p>
+ * <ul>
+ * <li><a href="/about/versions/10/behavior-changes-all">Behavior changes: all apps</a></li>
+ * <li><a href="/about/versions/10/behavior-changes-10">Behavior changes: apps targeting API
+ * 29+</a></li>
+ * </ul>
+ *
*/
public static final int Q = 29;
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 653a559..f9e146a 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -17,6 +17,7 @@
package android.os;
import android.view.Display;
+import android.view.KeyEvent;
import java.util.function.Consumer;
@@ -319,4 +320,7 @@
/** Returns information about the last wakeup event. */
public abstract PowerManager.WakeData getLastWakeup();
+
+ /** Allows power button to intercept a power key button press. */
+ public abstract boolean interceptPowerKeyDown(KeyEvent event);
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index a4077fb..efea953 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -947,7 +947,7 @@
/**
* Enable or disable the freezer. When enable == false all frozen processes are unfrozen,
- * but aren't removed from the freezer. Processes can still be added or removed
+ * but aren't removed from the freezer. While in this state, processes can be added or removed
* by using setProcessFrozen, but they won't actually be frozen until the freezer is enabled
* again. If enable == true the freezer is enabled again, and all processes
* in the freezer (including the ones added while the freezer was disabled) are frozen.
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 8ad35e7..e2e6140 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -35,6 +35,8 @@
import android.annotation.SystemApi;
import android.app.Service;
import android.app.admin.DevicePolicyManager.PermissionGrantState;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -83,6 +85,15 @@
public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
/**
+ * A ChangeId indicating that this device supports camera and mic indicators. Will be "false"
+ * if present, because the CompatChanges#isChangeEnabled method returns true if the change id
+ * is not present.
+ */
+ @ChangeId
+ @Disabled
+ private static final long CAMERA_MIC_INDICATORS_NOT_PRESENT = 162547999L;
+
+ /**
* Revoke a set of runtime permissions for various apps.
*
* @param requests The permissions to revoke as {@code Map<packageName, List<permission>>}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f395569..10ac27c 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8929,6 +8929,14 @@
public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
/**
+ * Controls which packages are blocked from persisting in media controls when resumption is
+ * enabled. The list of packages is set by the user in the Settings app.
+ * @see Settings.Secure#MEDIA_CONTROLS_RESUME
+ * @hide
+ */
+ public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked";
+
+ /**
* Controls if window magnification is enabled.
* @hide
*/
@@ -8958,6 +8966,13 @@
public static final int ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW = 0x2;
/**
+ * Whether the Adaptive connectivity option is enabled.
+ *
+ * @hide
+ */
+ public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled";
+
+ /**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
*
diff --git a/core/java/android/service/autofill/InlinePresentation.java b/core/java/android/service/autofill/InlinePresentation.java
index 91416948..6eb2a15 100644
--- a/core/java/android/service/autofill/InlinePresentation.java
+++ b/core/java/android/service/autofill/InlinePresentation.java
@@ -40,6 +40,11 @@
/**
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
*/
private final @NonNull Slice mSlice;
@@ -90,6 +95,11 @@
*
* @param slice
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
* @param inlinePresentationSpec
* Specifies the UI specification for the inline suggestion.
* @param pinned
@@ -118,6 +128,11 @@
/**
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
*/
@DataClass.Generated.Member
public @NonNull Slice getSlice() {
@@ -244,7 +259,7 @@
};
@DataClass.Generated(
- time = 1593131904745L,
+ time = 1596484869201L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java",
inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)")
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 408e850..2b8649f 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -62,17 +62,17 @@
* to release the native resources used by the TextToSpeech engine.
*
* Apps targeting Android 11 that use text-to-speech should declare {@link
- * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the <code><queries></code> elements of their
+ * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their
* manifest:
*
- * <code>
- * <queries>
+ * <pre>
+ * <queries>
* ...
- * <intent>
- * <action android:name="android.intent.action.TTS_SERVICE" />
- * </intent>
- * </queries>
- * </code>
+ * <intent>
+ * <action android:name="android.intent.action.TTS_SERVICE" />
+ * </intent>
+ * </queries>
+ * </pre>
*/
public class TextToSpeech {
@@ -254,18 +254,17 @@
* </ul>
*
* Apps targeting Android 11 that use text-to-speech should declare {@link
- * #INTENT_ACTION_TTS_SERVICE} in the <code><queries></code> elements of their
+ * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their
* manifest:
*
- * <code>
- * <queries>
+ * <pre>
+ * <queries>
* ...
- * <intent>
- * <action android:name="android.intent.action.TTS_SERVICE" />
- * </intent>
- * </queries>
- * </code>
-
+ * <intent>
+ * <action android:name="android.intent.action.TTS_SERVICE" />
+ * </intent>
+ * </queries>
+ * </pre>
*/
public class Engine {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 7f45c04..403ac3a 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -629,7 +629,7 @@
if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged");
mHost.notifyInsetsChanged();
}
- if (!mState.equals(state, true /* excludingCaptionInsets */,
+ if (!mState.equals(mLastDispatchedState, true /* excludingCaptionInsets */,
true /* excludeInvisibleIme */)) {
if (DEBUG) Log.d(TAG, "onStateChanged, send state to WM: " + mState);
updateRequestedState();
@@ -1138,15 +1138,14 @@
if (invokeCallback) {
control.cancel();
}
+ boolean stateChanged = false;
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
RunningAnimation runningAnimation = mRunningAnimations.get(i);
if (runningAnimation.runner == control) {
mRunningAnimations.remove(i);
ArraySet<Integer> types = toInternalType(control.getTypes());
for (int j = types.size() - 1; j >= 0; j--) {
- if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) {
- mHost.notifyInsetsChanged();
- }
+ stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
}
if (invokeCallback && runningAnimation.startDispatched) {
dispatchAnimationEnd(runningAnimation.runner.getAnimation());
@@ -1154,6 +1153,10 @@
break;
}
}
+ if (stateChanged) {
+ mHost.notifyInsetsChanged();
+ updateRequestedState();
+ }
}
private void applyLocalVisibilityOverride() {
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 6b0b509..593b37a 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -60,6 +60,8 @@
*/
public class InsetsState implements Parcelable {
+ public static final InsetsState EMPTY = new InsetsState();
+
/**
* Internal representation of inset source types. This is different from the public API in
* {@link WindowInsets.Type} as one type from the public API might indicate multiple windows
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 0c50cb7..7a467d6 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -52,13 +52,11 @@
private View mHeaderText;
private View mSecondaryHeaderText;
private OnClickListener mExpandClickListener;
- private OnClickListener mAppOpsListener;
private HeaderTouchListener mTouchListener = new HeaderTouchListener();
private LinearLayout mTransferChip;
private NotificationExpandButton mExpandButton;
private CachingIconView mIcon;
private View mProfileBadge;
- private View mAppOps;
private boolean mExpanded;
private boolean mShowExpandButtonAtEnd;
private boolean mShowWorkBadgeAtEnd;
@@ -115,7 +113,6 @@
mExpandButton = findViewById(com.android.internal.R.id.expand_button);
mIcon = findViewById(com.android.internal.R.id.icon);
mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
- mAppOps = findViewById(com.android.internal.R.id.app_ops);
}
@Override
@@ -143,7 +140,6 @@
// Icons that should go at the end
if ((child == mExpandButton && mShowExpandButtonAtEnd)
|| child == mProfileBadge
- || child == mAppOps
|| child == mTransferChip) {
iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
} else {
@@ -208,7 +204,6 @@
// Icons that should go at the end
if ((child == mExpandButton && mShowExpandButtonAtEnd)
|| child == mProfileBadge
- || child == mAppOps
|| child == mTransferChip) {
if (end == getMeasuredWidth()) {
layoutRight = end - mContentEndMargin;
@@ -277,22 +272,10 @@
}
private void updateTouchListener() {
- if (mExpandClickListener == null && mAppOpsListener == null) {
- setOnTouchListener(null);
- return;
- }
setOnTouchListener(mTouchListener);
mTouchListener.bindTouchRects();
}
- /**
- * Sets onclick listener for app ops icons.
- */
- public void setAppOpsOnClickListener(OnClickListener l) {
- mAppOpsListener = l;
- updateTouchListener();
- }
-
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
mExpandClickListener = l;
@@ -380,7 +363,6 @@
private final ArrayList<Rect> mTouchRects = new ArrayList<>();
private Rect mExpandButtonRect;
- private Rect mAppOpsRect;
private int mTouchSlop;
private boolean mTrackGesture;
private float mDownX;
@@ -393,8 +375,6 @@
mTouchRects.clear();
addRectAroundView(mIcon);
mExpandButtonRect = addRectAroundView(mExpandButton);
- mAppOpsRect = addRectAroundView(mAppOps);
- setTouchDelegate(new TouchDelegate(mAppOpsRect, mAppOps));
addWidthRect();
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@@ -455,11 +435,6 @@
break;
case MotionEvent.ACTION_UP:
if (mTrackGesture) {
- if (mAppOps.isVisibleToUser() && (mAppOpsRect.contains((int) x, (int) y)
- || mAppOpsRect.contains((int) mDownX, (int) mDownY))) {
- mAppOps.performClick();
- return true;
- }
mExpandButton.performClick();
}
break;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 288c28b..49d456b 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -387,6 +387,7 @@
private final SuggestionHelper mSuggestionHelper = new SuggestionHelper();
private boolean mFlagCursorDragFromAnywhereEnabled;
+ private float mCursorDragDirectionMinXYRatio;
private boolean mFlagInsertionHandleGesturesEnabled;
// Specifies whether the new magnifier (with fish-eye effect) is enabled.
@@ -423,6 +424,11 @@
mFlagCursorDragFromAnywhereEnabled = AppGlobals.getIntCoreSetting(
WidgetFlags.KEY_ENABLE_CURSOR_DRAG_FROM_ANYWHERE,
WidgetFlags.ENABLE_CURSOR_DRAG_FROM_ANYWHERE_DEFAULT ? 1 : 0) != 0;
+ final int cursorDragMinAngleFromVertical = AppGlobals.getIntCoreSetting(
+ WidgetFlags.KEY_CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL,
+ WidgetFlags.CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL_DEFAULT);
+ mCursorDragDirectionMinXYRatio = EditorTouchState.getXYRatio(
+ cursorDragMinAngleFromVertical);
mFlagInsertionHandleGesturesEnabled = AppGlobals.getIntCoreSetting(
WidgetFlags.KEY_ENABLE_INSERTION_HANDLE_GESTURES,
WidgetFlags.ENABLE_INSERTION_HANDLE_GESTURES_DEFAULT ? 1 : 0) != 0;
@@ -432,6 +438,8 @@
if (TextView.DEBUG_CURSOR) {
logCursor("Editor", "Cursor drag from anywhere is %s.",
mFlagCursorDragFromAnywhereEnabled ? "enabled" : "disabled");
+ logCursor("Editor", "Cursor drag min angle from vertical is %d (= %f x/y ratio)",
+ cursorDragMinAngleFromVertical, mCursorDragDirectionMinXYRatio);
logCursor("Editor", "Insertion handle gestures is %s.",
mFlagInsertionHandleGesturesEnabled ? "enabled" : "disabled");
logCursor("Editor", "New magnifier is %s.",
@@ -458,6 +466,11 @@
}
@VisibleForTesting
+ public void setCursorDragMinAngleFromVertical(int degreesFromVertical) {
+ mCursorDragDirectionMinXYRatio = EditorTouchState.getXYRatio(degreesFromVertical);
+ }
+
+ @VisibleForTesting
public boolean getFlagInsertionHandleGesturesEnabled() {
return mFlagInsertionHandleGesturesEnabled;
}
@@ -6129,10 +6142,11 @@
if (mIsDraggingCursor) {
performCursorDrag(event);
} else if (mFlagCursorDragFromAnywhereEnabled
- && mTextView.getLayout() != null
- && mTextView.isFocused()
- && mTouchState.isMovedEnoughForDrag()
- && !mTouchState.isDragCloseToVertical()) {
+ && mTextView.getLayout() != null
+ && mTextView.isFocused()
+ && mTouchState.isMovedEnoughForDrag()
+ && (mTouchState.getInitialDragDirectionXYRatio()
+ > mCursorDragDirectionMinXYRatio || mTouchState.isOnHandle())) {
startCursorDrag(event);
}
break;
diff --git a/core/java/android/widget/EditorTouchState.java b/core/java/android/widget/EditorTouchState.java
index 9eb63087..75143686 100644
--- a/core/java/android/widget/EditorTouchState.java
+++ b/core/java/android/widget/EditorTouchState.java
@@ -59,7 +59,7 @@
private boolean mMultiTapInSameArea;
private boolean mMovedEnoughForDrag;
- private boolean mIsDragCloseToVertical;
+ private float mInitialDragDirectionXYRatio;
public float getLastDownX() {
return mLastDownX;
@@ -98,8 +98,23 @@
return mMovedEnoughForDrag;
}
- public boolean isDragCloseToVertical() {
- return mIsDragCloseToVertical && !mIsOnHandle;
+ /**
+ * When {@link #isMovedEnoughForDrag()} is {@code true}, this function returns the x/y ratio for
+ * the initial drag direction. Smaller values indicate that the direction is closer to vertical,
+ * while larger values indicate that the direction is closer to horizontal. For example:
+ * <ul>
+ * <li>if the drag direction is exactly vertical, this returns 0
+ * <li>if the drag direction is exactly horizontal, this returns {@link Float#MAX_VALUE}
+ * <li>if the drag direction is 45 deg from vertical, this returns 1
+ * <li>if the drag direction is 30 deg from vertical, this returns 0.58 (x delta is smaller
+ * than y delta)
+ * <li>if the drag direction is 60 deg from vertical, this returns 1.73 (x delta is bigger
+ * than y delta)
+ * </ul>
+ * This function never returns negative values, regardless of the direction of the drag.
+ */
+ public float getInitialDragDirectionXYRatio() {
+ return mInitialDragDirectionXYRatio;
}
public void setIsOnHandle(boolean onHandle) {
@@ -155,7 +170,7 @@
mLastDownY = event.getY();
mLastDownMillis = event.getEventTime();
mMovedEnoughForDrag = false;
- mIsDragCloseToVertical = false;
+ mInitialDragDirectionXYRatio = 0.0f;
} else if (action == MotionEvent.ACTION_UP) {
if (TextView.DEBUG_CURSOR) {
logCursor("EditorTouchState", "ACTION_UP");
@@ -164,7 +179,7 @@
mLastUpY = event.getY();
mLastUpMillis = event.getEventTime();
mMovedEnoughForDrag = false;
- mIsDragCloseToVertical = false;
+ mInitialDragDirectionXYRatio = 0.0f;
} else if (action == MotionEvent.ACTION_MOVE) {
if (!mMovedEnoughForDrag) {
float deltaX = event.getX() - mLastDownX;
@@ -174,9 +189,8 @@
int touchSlop = config.getScaledTouchSlop();
mMovedEnoughForDrag = distanceSquared > touchSlop * touchSlop;
if (mMovedEnoughForDrag) {
- // If the direction of the swipe motion is within 45 degrees of vertical, it is
- // considered a vertical drag.
- mIsDragCloseToVertical = Math.abs(deltaX) <= Math.abs(deltaY);
+ mInitialDragDirectionXYRatio = (deltaY == 0) ? Float.MAX_VALUE :
+ Math.abs(deltaX / deltaY);
}
}
} else if (action == MotionEvent.ACTION_CANCEL) {
@@ -185,7 +199,7 @@
mMultiTapStatus = MultiTapStatus.NONE;
mMultiTapInSameArea = false;
mMovedEnoughForDrag = false;
- mIsDragCloseToVertical = false;
+ mInitialDragDirectionXYRatio = 0.0f;
}
}
@@ -201,4 +215,27 @@
float distanceSquared = (deltaX * deltaX) + (deltaY * deltaY);
return distanceSquared <= maxDistance * maxDistance;
}
+
+ /**
+ * Returns the x/y ratio corresponding to the given angle relative to vertical. Smaller angle
+ * values (ie, closer to vertical) will result in a smaller x/y ratio. For example:
+ * <ul>
+ * <li>if the angle is 45 deg, the ratio is 1
+ * <li>if the angle is 30 deg, the ratio is 0.58 (x delta is smaller than y delta)
+ * <li>if the angle is 60 deg, the ratio is 1.73 (x delta is bigger than y delta)
+ * </ul>
+ * If the passed-in value is <= 0, this function returns 0. If the passed-in value is >= 90,
+ * this function returns {@link Float#MAX_VALUE}.
+ *
+ * @see #getInitialDragDirectionXYRatio()
+ */
+ public static float getXYRatio(int angleFromVerticalInDegrees) {
+ if (angleFromVerticalInDegrees <= 0) {
+ return 0.0f;
+ }
+ if (angleFromVerticalInDegrees >= 90) {
+ return Float.MAX_VALUE;
+ }
+ return (float) Math.tan(Math.toRadians(angleFromVerticalInDegrees));
+ }
}
diff --git a/core/java/android/widget/WidgetFlags.java b/core/java/android/widget/WidgetFlags.java
index 09ab5aa..e272086 100644
--- a/core/java/android/widget/WidgetFlags.java
+++ b/core/java/android/widget/WidgetFlags.java
@@ -41,6 +41,28 @@
public static final boolean ENABLE_CURSOR_DRAG_FROM_ANYWHERE_DEFAULT = true;
/**
+ * Threshold for the direction of a swipe gesture in order for it to be handled as a cursor drag
+ * rather than a scroll. The direction angle of the swipe gesture must exceed this value in
+ * order to trigger cursor drag; otherwise, the swipe will be assumed to be a scroll gesture.
+ * The value units for this flag is degrees and the valid range is [0,90] inclusive. If a value
+ * < 0 is set, 0 will be used instead; if a value > 90 is set, 90 will be used instead.
+ */
+ public static final String CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL =
+ "CursorControlFeature__min_angle_from_vertical_to_start_cursor_drag";
+
+ /**
+ * The key used in app core settings for the flag
+ * {@link #CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL}.
+ */
+ public static final String KEY_CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL =
+ "widget__min_angle_from_vertical_to_start_cursor_drag";
+
+ /**
+ * Default value for the flag {@link #CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL}.
+ */
+ public static final int CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL_DEFAULT = 45;
+
+ /**
* The flag of finger-to-cursor distance in DP for cursor dragging.
* The value unit is DP and the range is {0..100}. If the value is out of range, the legacy
* value, which is based on handle size, will be used.
diff --git a/core/java/android/widget/inline/InlinePresentationSpec.java b/core/java/android/widget/inline/InlinePresentationSpec.java
index 5f924c6..e7727fd 100644
--- a/core/java/android/widget/inline/InlinePresentationSpec.java
+++ b/core/java/android/widget/inline/InlinePresentationSpec.java
@@ -42,8 +42,13 @@
private final Size mMaxSize;
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -123,8 +128,13 @@
}
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -264,8 +274,13 @@
}
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -302,7 +317,7 @@
}
@DataClass.Generated(
- time = 1588109681295L,
+ time = 1596485189661L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/widget/inline/InlinePresentationSpec.java",
inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.NonNull android.os.Bundle mStyle\nprivate static @android.annotation.NonNull android.os.Bundle defaultStyle()\nprivate boolean styleEquals(android.os.Bundle)\npublic void filterContentTypes()\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 49ad81b..fe77478 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -784,8 +784,8 @@
FrameworkStatsLog.SHARESHEET_STARTED,
getReferrerPackageName(),
target.getType(),
- initialIntents == null ? 0 : initialIntents.length,
mCallerChooserTargets == null ? 0 : mCallerChooserTargets.length,
+ initialIntents == null ? 0 : initialIntents.length,
isWorkProfile(),
findPreferredContentPreview(getTargetIntent(), getContentResolver()),
target.getAction()
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index ea3d2de..eb59f0f 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -123,10 +123,15 @@
// Flag related to Privacy Indicators
/**
- * Whether the Permissions Hub is showing.
+ * Whether to show the complete ongoing app ops chip.
*/
public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_2_enabled";
+ /**
+ * Whether to show app ops chip for just microphone + camera.
+ */
+ public static final String PROPERTY_MIC_CAMERA_ENABLED = "camera_mic_icons_enabled";
+
// Flags related to Assistant
/**
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a50a522..3b5fecf 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -113,6 +113,14 @@
// Default is no-op
}
+ /**
+ * Callback indicating that the given document has been deleted or moved. This gives
+ * the provider a hook to revoke the uri permissions.
+ */
+ protected void onDocIdDeleted(String docId) {
+ // Default is no-op
+ }
+
@Override
public boolean onCreate() {
throw new UnsupportedOperationException(
@@ -283,6 +291,7 @@
final String afterDocId = getDocIdForFile(after);
onDocIdChanged(docId);
+ onDocIdDeleted(docId);
onDocIdChanged(afterDocId);
final File afterVisibleFile = getFileForDocId(afterDocId, true);
@@ -312,6 +321,7 @@
final String docId = getDocIdForFile(after);
onDocIdChanged(sourceDocumentId);
+ onDocIdDeleted(sourceDocumentId);
onDocIdChanged(docId);
moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
@@ -343,6 +353,7 @@
}
onDocIdChanged(docId);
+ onDocIdDeleted(docId);
removeFromMediaStore(visibleFile);
}
diff --git a/core/java/com/android/internal/os/logging/MetricsLoggerWrapper.java b/core/java/com/android/internal/os/logging/MetricsLoggerWrapper.java
index ba60fa5..b42ea7d 100644
--- a/core/java/com/android/internal/os/logging/MetricsLoggerWrapper.java
+++ b/core/java/com/android/internal/os/logging/MetricsLoggerWrapper.java
@@ -16,14 +16,8 @@
package com.android.internal.os.logging;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.util.Pair;
import android.view.WindowManager.LayoutParams;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.FrameworkStatsLog;
/**
@@ -32,81 +26,6 @@
*/
public class MetricsLoggerWrapper {
- private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
- private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1;
-
- public static void logPictureInPictureDismissByTap(Context context,
- Pair<ComponentName, Integer> topActivityInfo) {
- MetricsLogger.action(context, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
- METRIC_VALUE_DISMISSED_BY_TAP);
- FrameworkStatsLog.write(FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED,
- getUid(context, topActivityInfo.first, topActivityInfo.second),
- topActivityInfo.first.flattenToString(),
- FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED__STATE__DISMISSED);
- }
-
- public static void logPictureInPictureDismissByDrag(Context context,
- Pair<ComponentName, Integer> topActivityInfo) {
- MetricsLogger.action(context,
- MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
- METRIC_VALUE_DISMISSED_BY_DRAG);
- FrameworkStatsLog.write(FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED,
- getUid(context, topActivityInfo.first, topActivityInfo.second),
- topActivityInfo.first.flattenToString(),
- FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED__STATE__DISMISSED);
- }
-
- public static void logPictureInPictureMinimize(Context context, boolean isMinimized,
- Pair<ComponentName, Integer> topActivityInfo) {
- MetricsLogger.action(context, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MINIMIZED,
- isMinimized);
- FrameworkStatsLog.write(FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED,
- getUid(context, topActivityInfo.first, topActivityInfo.second),
- topActivityInfo.first.flattenToString(),
- FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED__STATE__MINIMIZED);
- }
-
- /**
- * Get uid from component name and user Id
- * @return uid. -1 if not found.
- */
- private static int getUid(Context context, ComponentName componentName, int userId) {
- int uid = -1;
- if (componentName == null) {
- return uid;
- }
- try {
- uid = context.getPackageManager().getApplicationInfoAsUser(
- componentName.getPackageName(), 0, userId).uid;
- } catch (NameNotFoundException e) {
- }
- return uid;
- }
-
- public static void logPictureInPictureMenuVisible(Context context, boolean menuStateFull) {
- MetricsLogger.visibility(context, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU,
- menuStateFull);
- }
-
- public static void logPictureInPictureEnter(Context context,
- int uid, String shortComponentName, boolean supportsEnterPipOnTaskSwitch) {
- MetricsLogger.action(context, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
- supportsEnterPipOnTaskSwitch);
- FrameworkStatsLog.write(FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED, uid,
- shortComponentName,
- FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED__STATE__ENTERED);
- }
-
- public static void logPictureInPictureFullScreen(Context context, int uid,
- String shortComponentName) {
- MetricsLogger.action(context,
- MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
- FrameworkStatsLog.write(FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED,
- uid,
- shortComponentName,
- FrameworkStatsLog.PICTURE_IN_PICTURE_STATE_CHANGED__STATE__EXPANDED_TO_FULL_SCREEN);
- }
-
public static void logAppOverlayEnter(int uid, String packageName, boolean changed, int type, boolean usingAlertWindow) {
if (changed) {
if (type != LayoutParams.TYPE_APPLICATION_OVERLAY) {
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 9bf0513..a23fc4b 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -291,7 +291,7 @@
};
Message msg = Message.obtain(null, screenshotType, screenshotRequest);
- final ServiceConnection myConn = mScreenshotConnection;
+
Handler h = new Handler(handler.getLooper()) {
@Override
public void handleMessage(Message msg) {
@@ -304,8 +304,8 @@
break;
case SCREENSHOT_MSG_PROCESS_COMPLETE:
synchronized (mScreenshotLock) {
- if (myConn != null && mScreenshotConnection == myConn) {
- mContext.unbindService(myConn);
+ if (mScreenshotConnection != null) {
+ mContext.unbindService(mScreenshotConnection);
mScreenshotConnection = null;
mScreenshotService = null;
}
@@ -368,6 +368,7 @@
}
} else {
Messenger messenger = new Messenger(mScreenshotService);
+
try {
messenger.send(msg);
} catch (RemoteException e) {
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 0791ed3..e3a456c 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -167,8 +167,6 @@
private int mFacePileProtectionWidthExpanded;
private boolean mImportantConversation;
private TextView mUnreadBadge;
- private ViewGroup mAppOps;
- private Rect mAppOpsTouchRect = new Rect();
private float mMinTouchSize;
private Icon mConversationIcon;
private Icon mShortcutIcon;
@@ -210,7 +208,6 @@
mConversationIconView = findViewById(R.id.conversation_icon);
mConversationIconContainer = findViewById(R.id.conversation_icon_container);
mIcon = findViewById(R.id.icon);
- mAppOps = findViewById(com.android.internal.R.id.app_ops);
mMinTouchSize = 48 * getResources().getDisplayMetrics().density;
mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
@@ -1166,47 +1163,6 @@
}
});
}
- if (mAppOps.getWidth() > 0) {
-
- // Let's increase the touch size of the app ops view if it's here
- mAppOpsTouchRect.set(
- mAppOps.getLeft(),
- mAppOps.getTop(),
- mAppOps.getRight(),
- mAppOps.getBottom());
- for (int i = 0; i < mAppOps.getChildCount(); i++) {
- View child = mAppOps.getChildAt(i);
- if (child.getVisibility() == GONE) {
- continue;
- }
- // Make sure each child has at least a minTouchSize touch target around it
- float childTouchLeft = child.getLeft() + child.getWidth() / 2.0f
- - mMinTouchSize / 2.0f;
- float childTouchRight = childTouchLeft + mMinTouchSize;
- mAppOpsTouchRect.left = (int) Math.min(mAppOpsTouchRect.left,
- mAppOps.getLeft() + childTouchLeft);
- mAppOpsTouchRect.right = (int) Math.max(mAppOpsTouchRect.right,
- mAppOps.getLeft() + childTouchRight);
- }
-
- // Increase the height
- int heightIncrease = 0;
- if (mAppOpsTouchRect.height() < mMinTouchSize) {
- heightIncrease = (int) Math.ceil((mMinTouchSize - mAppOpsTouchRect.height())
- / 2.0f);
- }
- mAppOpsTouchRect.inset(0, -heightIncrease);
-
- // Let's adjust the hitrect since app ops isn't a direct child
- ViewGroup viewGroup = (ViewGroup) mAppOps.getParent();
- while (viewGroup != this) {
- mAppOpsTouchRect.offset(viewGroup.getLeft(), viewGroup.getTop());
- viewGroup = (ViewGroup) viewGroup.getParent();
- }
- //
- // Extend the size of the app opps to be at least 48dp
- setTouchDelegate(new TouchDelegate(mAppOpsTouchRect, mAppOps));
- }
}
public MessagingLinearLayout getMessagingLinearLayout() {
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index 2302de2..b4e108f 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +32,7 @@
* A class to extract Bitmaps from a MessagingStyle message.
*/
public class LocalImageResolver {
+ private static final String TAG = LocalImageResolver.class.getSimpleName();
private static final int MAX_SAFE_ICON_SIZE_PX = 480;
@@ -60,11 +62,18 @@
private static BitmapFactory.Options getBoundsOptionsForImage(Uri uri, Context context)
throws IOException {
- InputStream input = context.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
- onlyBoundsOptions.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
- input.close();
+ try (InputStream input = context.getContentResolver().openInputStream(uri)) {
+ if (input == null) {
+ throw new IllegalArgumentException();
+ }
+ onlyBoundsOptions.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
+ } catch (IllegalArgumentException iae) {
+ onlyBoundsOptions.outWidth = -1;
+ onlyBoundsOptions.outHeight = -1;
+ Log.e(TAG, "error loading image", iae);
+ }
return onlyBoundsOptions;
}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c32ca6..6becb07 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -346,22 +346,6 @@
}
}
-void android_os_Process_enableFreezer(
- JNIEnv *env, jobject clazz, jboolean enable)
-{
- bool success = true;
-
- if (enable) {
- success = SetTaskProfiles(0, {"FreezerFrozen"}, true);
- } else {
- success = SetTaskProfiles(0, {"FreezerThawed"}, true);
- }
-
- if (!success) {
- jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
- }
-}
-
jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid)
{
SchedPolicy sp;
@@ -1360,7 +1344,6 @@
{"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
{"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
{"setProcessFrozen", "(IIZ)V", (void*)android_os_Process_setProcessFrozen},
- {"enableFreezer", "(Z)V", (void*)android_os_Process_enableFreezer},
{"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
{"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},
{"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V",
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 7daefd3..26e862f 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -63,6 +63,7 @@
void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
int32_t configId, nsecs_t vsyncPeriod) override;
+ void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) override {}
};
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 69b32c2..2cfd6105 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2683,4 +2683,9 @@
// CATEGORY: SETTINGS
// OS: R
MEDIA_CONTROLS_SETTINGS = 1845;
+
+ // OPEN: Settings > Network & internet > Adaptive connectivity
+ // CATEGORY: SETTINGS
+ // OS: R QPR
+ ADAPTIVE_CONNECTIVITY_CATEGORY = 1850;
}
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index fe8a0f1..acf8cc4 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -180,6 +180,7 @@
optional SettingProto cmas_additional_broadcast_pkg = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
repeated SettingProto completed_categories = 15;
optional SettingProto connectivity_release_pending_intent_delay_ms = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto adaptive_connectivity_enabled = 84 [ (android.privacy).dest = DEST_AUTOMATIC ];
message Controls {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -595,5 +596,5 @@
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 82;
+ // Next tag = 85;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9945057..d0ca0a8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1340,7 +1340,7 @@
android:priority="800" />
<!-- Allows an application to access data from sensors that the user uses to
- measure what is happening inside his/her body, such as heart rate.
+ measure what is happening inside their body, such as heart rate.
<p>Protection level: dangerous -->
<permission android:name="android.permission.BODY_SENSORS"
android:permissionGroup="android.permission-group.UNDEFINED"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 23b8bd3..03e130e 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -146,43 +146,6 @@
android:visibility="gone"
android:contentDescription="@string/notification_work_profile_content_description"
/>
- <LinearLayout
- android:id="@+id/app_ops"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:layout_marginStart="6dp"
- android:background="?android:selectableItemBackgroundBorderless"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/camera"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_camera"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_camera_active"
- />
- <ImageView
- android:id="@+id/mic"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_mic"
- android:layout_marginStart="4dp"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_microphone_active"
- />
- <ImageView
- android:id="@+id/overlay"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_alert_window_layer"
- android:layout_marginStart="4dp"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_overlay_active"
- />
- </LinearLayout>
<include
layout="@layout/notification_material_media_transfer_action"
android:id="@+id/media_seamless"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index cc4eb5a..6978a9a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -513,9 +513,9 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"الدخول إلى إعدادات بلوتوث"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بإعداد لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"للسماح للتطبيق بضبط البلوتوث على جهاز Android TV واكتشاف الأجهزة البعيدة والاقتران بها."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بإعداد هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"الاتصال بـشبكة WiMAX وقطع الاتصال بها"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"للسماح للتطبيق بتحديد ما إذا تم تفعيل WiMAX وتحديد معلومات حول أي شبكات WiMAX متصلة."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"تغيير حالة WiMAX"</string>
@@ -1409,7 +1409,7 @@
<string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
<string name="show_ime" msgid="6406112007347443383">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
<string name="hardware" msgid="1800597768237606953">"إظهار لوحة المفاتيح الافتراضية"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"تهيئة لوحة المفاتيح الفعلية"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"إعداد لوحة المفاتيح الفعلية"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"انقر لاختيار لغة وتنسيق"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index cbafe4f..4ff2a6a 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"স্পেচ"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"লিখক"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"মচক"</string>
- <string name="search_go" msgid="2141477624421347086">"অনুসন্ধান কৰক"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"অনুসন্ধান কৰক…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"অনুসন্ধান কৰক"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"প্ৰশ্নৰ সন্ধান কৰক"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"প্ৰশ্ন মচক"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"প্ৰশ্ন দাখিল কৰক"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ৱিজেট যোগ কৰিব পৰা নগ\'ল।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যাওক"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"অনুসন্ধান কৰক"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"পঠিয়াওক"</string>
<string name="ime_action_next" msgid="4169702997635728543">"পৰৱৰ্তী"</string>
<string name="ime_action_done" msgid="6299921014822891569">"সম্পন্ন হ’ল"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"প্ৰস্তাৱিত"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"সকলো ভাষা"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"সকলো অঞ্চল"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"অনুসন্ধান কৰক"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"এপটো নাই"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"এই মুহূৰ্তত <xliff:g id="APP_NAME_0">%1$s</xliff:g> উপলব্ধ নহয়। ইয়াক <xliff:g id="APP_NAME_1">%2$s</xliff:g>এ পৰিচালনা কৰে।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"অধিক জানক"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c096fa5a..74f0e68f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -973,7 +973,7 @@
<string name="save_password_remember" msgid="6490888932657708341">"Запомніць"</string>
<string name="save_password_never" msgid="6776808375903410659">"Ніколі"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
- <string name="text_copied" msgid="2531420577879738860">"Тэкст скапіяваны ў буфер абмену."</string>
+ <string name="text_copied" msgid="2531420577879738860">"Тэкст скапіраваны ў буфер абмену."</string>
<string name="copied" msgid="4675902854553014676">"Скапіравана"</string>
<string name="more_item_label" msgid="7419249600215749115">"Больш"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 09b69db..1b75ac2 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"স্পেস"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"মুছুন"</string>
- <string name="search_go" msgid="2141477624421347086">"খুঁজুন"</string>
+ <string name="search_go" msgid="2141477624421347086">"সার্চ"</string>
<string name="search_hint" msgid="455364685740251925">"সার্চ করুন..."</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"খুঁজুন"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"সার্চ"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"সার্চ ক্যোয়ারী"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ক্যোয়ারী সাফ করুন"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ক্যোয়ারী জমা দিন"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"উইজেট যোগ করা যায়নি৷"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যান"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"খুঁজুন"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"সার্চ"</string>
<string name="ime_action_send" msgid="8456843745664334138">"পাঠান"</string>
<string name="ime_action_next" msgid="4169702997635728543">"পরবর্তী"</string>
<string name="ime_action_done" msgid="6299921014822891569">"সম্পন্ন হয়েছে"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"প্রস্তাবিত"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"সকল ভাষা"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"সমস্ত অঞ্চল"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"খুঁজুন"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"সার্চ"</string>
<string name="app_suspended_title" msgid="888873445010322650">"অ্যাপটি উপলভ্য নয়"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> এখন উপলভ্য নয়। এই অ্যাপটিকে <xliff:g id="APP_NAME_1">%2$s</xliff:g> অ্যাপ ম্যানেজ করে।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"আরও জানুন"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5a9fef3..6529de8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -468,10 +468,10 @@
<string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet que l\'aplicació impedeixi que la tauleta entri en repòs."</string>
<string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet que l\'aplicació impedeixi que el dispositiu Android TV entri en repòs."</string>
<string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet que l\'aplicació impedeixi que el telèfon entri en repòs."</string>
- <string name="permlab_transmitIr" msgid="8077196086358004010">"transmissió d\'infraroigs"</string>
- <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs de la tauleta."</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet que l\'aplicació faci servir el transmissor d\'infraroigs del dispositiu Android TV."</string>
- <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs del telèfon."</string>
+ <string name="permlab_transmitIr" msgid="8077196086358004010">"transmissió d\'infrarojos"</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet que l\'aplicació utilitzi el transmissor d\'infrarojos de la tauleta."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet que l\'aplicació faci servir el transmissor d\'infrarojos del dispositiu Android TV."</string>
+ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet que l\'aplicació utilitzi el transmissor d\'infrarojos del telèfon."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"establir fons de pantalla"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet que l\'aplicació estableixi el fons de pantalla del sistema."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"ajustament de la mida del fons de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7e5d6f2..e16c8c2 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1258,7 +1258,7 @@
<string name="volume_ringtone" msgid="134784084629229029">"Hlasitost vyzvánění"</string>
<string name="volume_music" msgid="7727274216734955095">"Hlasitost médií"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Přehrávání pomocí rozhraní Bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Je nastaven tichý vyzváněcí tón"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Je nastaven tichý vyzvánění"</string>
<string name="volume_call" msgid="7625321655265747433">"Hlasitost hovoru"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Hlasitost příchozích hovorů při připojení Bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Hlasitost budíku"</string>
@@ -1269,10 +1269,10 @@
<string name="volume_icon_description_incall" msgid="4491255105381227919">"Hlasitost hovoru"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"Hlasitost médií"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"Hlasitost oznámení"</string>
- <string name="ringtone_default" msgid="9118299121288174597">"Výchozí vyzváněcí tón"</string>
+ <string name="ringtone_default" msgid="9118299121288174597">"Výchozí vyzvánění"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Výchozí (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"Žádný"</string>
- <string name="ringtone_picker_title" msgid="667342618626068253">"Vyzváněcí tóny"</string>
+ <string name="ringtone_picker_title" msgid="667342618626068253">"Vyzvánění"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Zvuky budíku"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Zvuky upozornění"</string>
<string name="ringtone_unknown" msgid="5059495249862816475">"Neznámé"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index f428b1d..09e2ea2 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -654,7 +654,7 @@
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"observer netværksforhold"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"skift kalibrering for inputenheden"</string>
- <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Tillader, at appen ændrer kalibreringsparametrene for touchskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"få adgang til DRM-certifikater"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Tillader, at en applikation provisionerer og anvender DRM-certifikater. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"modtag status for Android Beam-overførsler"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a2ce798..b8c00d0 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1937,7 +1937,7 @@
<item quantity="one">Una sugerencia de Autocompletar</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"¿Quieres guardar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"¿Quieres guardar <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"¿Quieres guardar la <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"¿Quieres guardar <xliff:g id="TYPE_0">%1$s</xliff:g> y <xliff:g id="TYPE_1">%2$s</xliff:g> en "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_3types" msgid="6598228952100102578">"¿Quieres guardar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g> en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title" msgid="3630695947047069136">"¿Quieres actualizar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index cd3e6f7..c0ec8e0 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -482,8 +482,8 @@
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Telefonoaren ordu-zona aldatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_getAccounts" msgid="5304317160463582791">"bilatu gailuko kontuak"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Tabletak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dituzun aplikazioek sortutako kontuak egon litezke."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dituzun aplikazioek sortutako kontuak har daitezke barnean."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dauzkazun aplikazioek sortutako kontuak egon litezke."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"ikusi sareko konexioak"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Sareko konexioei buruzko informazioa ikusteko baimena ematen die aplikazioei; adibidez, zer sare dauden eta zeintzuk dauden konektatuta."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"izan sarerako sarbide osoa"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6ef746d..5ba54d3 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -982,7 +982,7 @@
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ડિલીટ કરો"</string>
<string name="search_go" msgid="2141477624421347086">"શોધો"</string>
<string name="search_hint" msgid="455364685740251925">"શોધો…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"શોધ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"શોધો"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"શોધ ક્વેરી"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ક્વેરી સાફ કરો"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ક્વેરી સબમિટ કરો"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 311d4ad..b531d02 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1894,7 +1894,7 @@
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Այս հավելվածը ստեղծվել է Android-ի ավելի հին տարբերակի համար և կարող է պատշաճ չաշխատել: Ստուգեք թարմացումների առկայությունը կամ դիմեք մշակողին:"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
- <string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS հավելվածը"</string>
+ <string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS-ների փոխանակման հավելվածը"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Որոշ գործառույթներ կարող են չաշխատել"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"Աշխատանքային պրոֆիլը կողպված է"</string>
<string name="profile_encrypted_message" msgid="1128512616293157802">"Հպեք՝ այն ապակողպելու համար"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 97bc116..b9e7f4f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -863,12 +863,12 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci perangkat Android TV menggunakan login Google.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, tablet akan direset ke setelan default pabrik dan semua data pengguna hilang."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal membuka kunci perangkat Android TV. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, perangkat Android TV akan direset ke default pabrik dan semua data pengguna akan hilang."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, ponsel akan direset ke setelan default pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan direset ke setelan default pabrik."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal membuka kunci perangkat Android TV. Perangkat Android TV sekarang akan direset ke default pabrik."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan direset ke setelan default pabrik."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Lupa pola?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Pembuka kunci akun"</string>
@@ -942,7 +942,7 @@
<string name="autofill_postal_code" msgid="7034789388968295591">"Kode pos"</string>
<string name="autofill_state" msgid="3341725337190434069">"Negara Bagian"</string>
<string name="autofill_zip_code" msgid="1315503730274962450">"Kode pos"</string>
- <string name="autofill_county" msgid="7781382735643492173">"Wilayah"</string>
+ <string name="autofill_county" msgid="7781382735643492173">"County"</string>
<string name="autofill_island" msgid="5367139008536593734">"Pulau"</string>
<string name="autofill_district" msgid="6428712062213557327">"Distrik"</string>
<string name="autofill_department" msgid="9047276226873531529">"Departemen"</string>
@@ -1435,7 +1435,7 @@
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Ubah setelan jaringan atau VPN"</string>
<string name="upload_file" msgid="8651942222301634271">"Pilih file"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"Tidak ada file yang dipilih"</string>
- <string name="reset" msgid="3865826612628171429">"Setel ulang"</string>
+ <string name="reset" msgid="3865826612628171429">"Reset"</string>
<string name="submit" msgid="862795280643405865">"Kirim"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Aplikasi mengemudi sedang berjalan"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Ketuk untuk keluar dari aplikasi mengemudi."</string>
@@ -1608,12 +1608,12 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, tablet akan direset ke setelan default pabrik dan semua data pengguna akan hilang."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal membuka kunci perangkat Android TV. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, perangkat Android TV akan direset ke default pabrik dan semua data pengguna akan hilang."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, ponsel akan direset ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan direset ke setelan default pabrik."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal membuka kunci perangkat Android TV. Perangkat Android TV sekarang akan direset ke default pabrik."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan direset ke setelan default pabrik."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci perangkat Android TV menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
@@ -1907,7 +1907,7 @@
<string name="app_info" msgid="6113278084877079851">"Info aplikasi"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Memulai demo..."</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"Menyetel ulang perangkat..."</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"Mereset perangkat..."</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
<string name="conference_call" msgid="5731633152336490471">"Konferensi Telepon"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Keterangan alat"</string>
@@ -2034,7 +2034,7 @@
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Aplikasi ini tidak diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Beranda"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Kembali"</string>
- <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplikasi yang Baru Dipakai"</string>
+ <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplikasi Terbaru"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifikasi"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Setelan Cepat"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialog Daya"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 791a6d2e..e39390f 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1937,7 +1937,7 @@
<item quantity="one">Un suggerimento di Compilazione automatica</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Vuoi salvare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vuoi salvare <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vuoi salvare la <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Vuoi salvare <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> su "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Vuoi salvare <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g> su "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title" msgid="3630695947047069136">"Vuoi aggiornare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 4d06726..1389753 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1199,7 +1199,7 @@
<string name="aerr_application_repeated" msgid="7804378743218496566">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> נעצרת שוב ושוב"</string>
<string name="aerr_process_repeated" msgid="1153152413537954974">"האפליקציה <xliff:g id="PROCESS">%1$s</xliff:g> נעצרת שוב ושוב"</string>
<string name="aerr_restart" msgid="2789618625210505419">"פתח שוב את האפליקציה"</string>
- <string name="aerr_report" msgid="3095644466849299308">"משוב"</string>
+ <string name="aerr_report" msgid="3095644466849299308">"שליחת משוב"</string>
<string name="aerr_close" msgid="3398336821267021852">"סגירה"</string>
<string name="aerr_mute" msgid="2304972923480211376">"השתק עד הפעלה מחדש של המכשיר"</string>
<string name="aerr_wait" msgid="3198677780474548217">"המתן"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fc60da7..4386a3d 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ಅಳಿಸಿ"</string>
- <string name="search_go" msgid="2141477624421347086">"ಹುಡುಕಿ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"ಹುಡುಕಿ…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"ಹುಡುಕಿ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"ಪ್ರಶ್ನೆಯನ್ನು ಹುಡುಕಿ"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ಪ್ರಶ್ನೆಯನ್ನು ತೆರವುಗೊಳಿಸು"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ಪ್ರಶ್ನೆಯನ್ನು ಸಲ್ಲಿಸು"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ಝೂಮ್ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ಹೋಗು"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"ಹುಡುಕಿ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"ಕಳುಹಿಸು"</string>
<string name="ime_action_next" msgid="4169702997635728543">"ಮುಂದೆ"</string>
<string name="ime_action_done" msgid="6299921014822891569">"ಮುಗಿದಿದೆ"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"ಸೂಚಿತ ಭಾಷೆ"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"ಎಲ್ಲಾ ಭಾಷೆಗಳು"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"ಎಲ್ಲಾ ಪ್ರದೇಶಗಳು"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"ಹುಡುಕಿ"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ. ಇದನ್ನು <xliff:g id="APP_NAME_1">%2$s</xliff:g> ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index efedc40..063bbbf 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1773,7 +1773,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Обиди се повторно подоцна"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Се прикажува на цел екран"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"За да излезете, повлечете одозгора надолу."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрав"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Сфатив"</string>
<string name="done_label" msgid="7283767013231718521">"Готово"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Приказ на часови во кружно движење"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Приказ на минути во кружно движење"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 3ccd9ec..94ac5ca 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"delete"</string>
- <string name="search_go" msgid="2141477624421347086">"തിരയൽ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"തിരയുക…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"തിരയൽ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"തിരയൽ അന്വേഷണം"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"അന്വേഷണം മായ്ക്കുക"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ചോദ്യം സമർപ്പിക്കുക"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"വിജറ്റ് ചേർക്കാനായില്ല."</string>
<string name="ime_action_go" msgid="5536744546326495436">"പോവുക"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"തിരയൽ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"അയയ്ക്കുക"</string>
<string name="ime_action_next" msgid="4169702997635728543">"അടുത്തത്"</string>
<string name="ime_action_done" msgid="6299921014822891569">"പൂർത്തിയായി"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"നിര്ദ്ദേശിച്ചത്"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"എല്ലാ ഭാഷകളും"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"എല്ലാ പ്രദേശങ്ങളും"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"തിരയുക"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ആപ്പ് ലഭ്യമല്ല"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ഇപ്പോൾ ലഭ്യമല്ല. <xliff:g id="APP_NAME_1">%2$s</xliff:g> ആണ് ഇത് മാനേജ് ചെയ്യുന്നത്."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"കൂടുതലറിയുക"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 621f2b5..b443f7e 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"स्पेस"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"एंटर"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"हटवा"</string>
- <string name="search_go" msgid="2141477624421347086">"शोध"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"शोधा…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"शोध"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"शोध क्वेरी"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"क्वेरी साफ करा"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"क्वेरी सबमिट करा"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"झूम नियंत्रणासाठी दोनदा टॅप करा"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट जोडू शकलो नाही."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जा"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"शोधा"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"पाठवा"</string>
<string name="ime_action_next" msgid="4169702997635728543">"पुढे"</string>
<string name="ime_action_done" msgid="6299921014822891569">"पूर्ण झाले"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"सुचवलेल्या भाषा"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"सर्व भाषा"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"सर्व प्रदेश"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"शोध"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"अॅप उपलब्ध नाही"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> आत्ता उपलब्ध नाही. हे <xliff:g id="APP_NAME_1">%2$s</xliff:g> कडून व्यवस्थापित केले जाते."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"अधिक जाणून घ्या"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 799ee93..520f973 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -302,13 +302,13 @@
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
<string name="permgrouplab_storage" msgid="1938416135375282333">"फाइल र मिडिया"</string>
- <string name="permgroupdesc_storage" msgid="6351503740613026600">"तपाईंको यन्त्रमा तस्बिर, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्"</string>
+ <string name="permgroupdesc_storage" msgid="6351503740613026600">"तपाईंको यन्त्रमा फोटो, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक क्रियाकलाप"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"आफ्नो शारीरिक क्रियाकलापको डेटामाथि पहुँच राख्नु"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"क्यामेरा"</string>
- <string name="permgroupdesc_camera" msgid="7585150538459320326">"तस्बिर खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
+ <string name="permgroupdesc_camera" msgid="7585150538459320326">"फोटो खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"कलका लगहरू"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कलको लग पढ्नुहोस् र लेख्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
@@ -435,10 +435,10 @@
<string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM लाई आदेश पठाउन एपलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।"</string>
<string name="permlab_activityRecognition" msgid="1782303296053990884">"शारीरिक गतिविधि पहिचान गर्नुहोस्"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"यो अनुप्रयोगले तपाईंको शारीरिक गतिविधिको पहिचान गर्न सक्छ।"</string>
- <string name="permlab_camera" msgid="6320282492904119413">"तस्बिरहरू र भिडियोहरू लिनुहोस्।"</string>
- <string name="permdesc_camera" msgid="1354600178048761499">"यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।"</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"एप वा सेवालाई तस्बिर र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
+ <string name="permlab_camera" msgid="6320282492904119413">"फोटोहरू र भिडियोहरू लिनुहोस्।"</string>
+ <string name="permdesc_camera" msgid="1354600178048761499">"यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ।"</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"एप वा सेवालाई फोटो र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"कुनै एप वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।"</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"कुनै क्यामेरा यन्त्र खोलिँदा (कुन अनुप्रयोगले खोलेको भन्ने बारेमा) वा बन्द गरिँदा यो अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।"</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"कम्पन नियन्त्रण गर्नुहोस्"</string>
@@ -1344,7 +1344,7 @@
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
<string name="ext_media_new_notification_message" msgid="6095403121990786986">"सेटअप गर्न ट्याप गर्नुहोस्"</string>
<string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"तपाईंले यो यन्त्र पुनः फर्म्याट गर्नु पर्ने हुन सक्छ। यो यन्त्र हटाउन ट्याप गर्नुहोस्।"</string>
- <string name="ext_media_ready_notification_message" msgid="777258143284919261">"तस्बिरहरू र मिडिया स्थानान्तरणका लागि"</string>
+ <string name="ext_media_ready_notification_message" msgid="777258143284919261">"फोटोहरू र मिडिया स्थानान्तरणका लागि"</string>
<string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> मा समस्या देखियो"</string>
<string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
<string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"समस्या समाधान गर्न ट्याप गर्नुहोस्"</string>
@@ -1633,7 +1633,7 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"तपाईंले <xliff:g id="SERVICE">%1$s</xliff:g> सक्रिय गर्नुभयो भने तपाईंको यन्त्रले डेटा इन्क्रिप्ट गर्ने सुविधाको स्तरोन्नति गर्न तपाईंको स्क्रिन लक सुविधाको प्रयोग गर्ने छैन।"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने अनुप्रयोगहरूमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने एपमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
@@ -1914,7 +1914,7 @@
<string name="app_category_game" msgid="4534216074910244790">"खेलहरू"</string>
<string name="app_category_audio" msgid="8296029904794676222">"सङ्गीत तथा अडियो"</string>
<string name="app_category_video" msgid="2590183854839565814">"चलचित्र तथा भिडियो"</string>
- <string name="app_category_image" msgid="7307840291864213007">"तस्बिर तथा छविहरू"</string>
+ <string name="app_category_image" msgid="7307840291864213007">"फोटो तथा छविहरू"</string>
<string name="app_category_social" msgid="2278269325488344054">"सामाजिक तथा सञ्चार"</string>
<string name="app_category_news" msgid="1172762719574964544">"समाचार तथा पत्रिकाहरू"</string>
<string name="app_category_maps" msgid="6395725487922533156">"नक्सा तथा नेभिगेसन"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index ccfc4ae..72fbc1d 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"ସ୍ପେସ୍"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର୍"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ୍"</string>
- <string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"କ୍ୱେରୀ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"କ୍ୱେରୀ ଖାଲି କରନ୍ତୁ"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"କ୍ୱେରୀ ଦାଖଲ କରନ୍ତୁ"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍ କରନ୍ତୁ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ୱିଜେଟ୍ ଯୋଡ଼ିପାରିବ ନାହିଁ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ଯାଆନ୍ତୁ"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"ପଠାନ୍ତୁ"</string>
<string name="ime_action_next" msgid="4169702997635728543">"ପରବର୍ତ୍ତୀ"</string>
<string name="ime_action_done" msgid="6299921014822891569">"ହୋଇଗଲା"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"ପ୍ରସ୍ତାବିତ"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"ସମସ୍ତ ଭାଷା"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"ସମସ୍ତ ଅଞ୍ଚଳ"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"ବର୍ତ୍ତମାନ <xliff:g id="APP_NAME_0">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ। ଏହା <xliff:g id="APP_NAME_1">%2$s</xliff:g> ଦ୍ଵାରା ପରିଚାଳିତ ହେଉଛି।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5c4c931..9554712 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1162,7 +1162,7 @@
<string name="capital_off" msgid="7443704171014626777">"IZKLOPLJENO"</string>
<string name="checked" msgid="9179896827054513119">"potrjeno"</string>
<string name="not_checked" msgid="7972320087569023342">"ni potrjeno"</string>
- <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z"</string>
+ <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z aplikacijo"</string>
<string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončanje dejanja z aplikacijo %1$s"</string>
<string name="whichApplicationLabel" msgid="7852182961472531728">"Izvedba dejanja"</string>
<string name="whichViewApplication" msgid="5733194231473132945">"Odpiranje z aplikacijo"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 8bc3682..d84b019 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -751,7 +751,7 @@
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"Faks shtëpie"</string>
<string name="phoneTypePager" msgid="576402072263522767">"Biper"</string>
<string name="phoneTypeOther" msgid="6918196243648754715">"Tjetër"</string>
- <string name="phoneTypeCallback" msgid="3455781500844157767">"Ri-telefono"</string>
+ <string name="phoneTypeCallback" msgid="3455781500844157767">"Kthim telefonate"</string>
<string name="phoneTypeCar" msgid="4604775148963129195">"Numri i telefonit të makinës"</string>
<string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Numri kryesor i telefonit të kompanisë"</string>
<string name="phoneTypeIsdn" msgid="2496238954533998512">"ISDN"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index b9cedeb..d9475d9 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"delete"</string>
- <string name="search_go" msgid="2141477624421347086">"వెతుకు"</string>
+ <string name="search_go" msgid="2141477624421347086">"సెర్చ్"</string>
<string name="search_hint" msgid="455364685740251925">"వెతుకు..."</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"శోధించండి"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"సెర్చ్"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"ప్రశ్నను శోధించండి"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయి"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ప్రశ్నని సమర్పించండి"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"విడ్జెట్ను జోడించడం సాధ్యపడలేదు."</string>
<string name="ime_action_go" msgid="5536744546326495436">"వెళ్లు"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"వెతుకు"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"సెర్చ్"</string>
<string name="ime_action_send" msgid="8456843745664334138">"పంపు"</string>
<string name="ime_action_next" msgid="4169702997635728543">"తర్వాత"</string>
<string name="ime_action_done" msgid="6299921014822891569">"పూర్తయింది"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"సూచించినవి"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"అన్ని భాషలు"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"అన్ని ప్రాంతాలు"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"వెతుకు"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"సెర్చ్"</string>
<string name="app_suspended_title" msgid="888873445010322650">"యాప్ అందుబాటులో లేదు"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు. ఇది <xliff:g id="APP_NAME_1">%2$s</xliff:g> ద్వారా నిర్వహించబడుతుంది."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"మరింత తెలుసుకోండి"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 50c29a6..bf7fbca 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1128,10 +1128,10 @@
<string name="whichViewApplication" msgid="5733194231473132945">"Mở bằng"</string>
<string name="whichViewApplicationNamed" msgid="415164730629690105">"Mở bằng %1$s"</string>
<string name="whichViewApplicationLabel" msgid="7367556735684742409">"Mở"</string>
- <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
- <string name="whichOpenLinksWith" msgid="1120936181362907258">"Mở đường dẫn liên kết bằng"</string>
- <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Mở đường dẫn liên kết bằng <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
- <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Mở đường liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
+ <string name="whichOpenLinksWith" msgid="1120936181362907258">"Mở đường liên kết bằng"</string>
+ <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Mở đường liên kết bằng <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Mở đường liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
<string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Cấp quyền truy cập"</string>
<string name="whichEditApplication" msgid="6191568491456092812">"Chỉnh sửa bằng"</string>
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Chỉnh sửa bằng %1$s"</string>
diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml
index 3a1679c..f46f70c 100644
--- a/core/res/res/values/donottranslate.xml
+++ b/core/res/res/values/donottranslate.xml
@@ -23,7 +23,7 @@
<!-- @hide DO NOT TRANSLATE. Control aspect ratio of lock pattern -->
<string name="lock_pattern_view_aspect">square</string>
<!-- @hide DO NOT TRANSLATE. ICU pattern for "Mon, 14 January" -->
- <string name="icu_abbrev_wday_month_day_no_year">eeeMMMMd</string>
+ <string name="icu_abbrev_wday_month_day_no_year">EEEMMMMd</string>
<!-- @hide DO NOT TRANSLATE. date formatting pattern for system ui.-->
<string name="system_ui_date_pattern">@string/icu_abbrev_wday_month_day_no_year</string>
<!-- @hide DO NOT TRANSLATE Spans within this text are applied to style composing regions
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index 777f4a3..de81ff4 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -19,6 +19,7 @@
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.google.common.truth.Truth.assertThat;
@@ -188,19 +189,38 @@
assertFalse(wrapper.isUiContext());
- wrapper = new ContextWrapper(new TestUiContext());
+ wrapper = new ContextWrapper(getUiContext());
assertTrue(wrapper.isUiContext());
}
- private static class TestUiContext extends ContextWrapper {
- TestUiContext() {
- super(null /* base */);
- }
+ @Test
+ public void testIsUiContext_UiContextDerivedContext() {
+ final Context uiContext = getUiContext();
+ Context context = uiContext.createAttributionContext(null /* attributionTag */);
- @Override
- public boolean isUiContext() {
- return true;
- }
+ assertTrue(context.isUiContext());
+
+ context = uiContext.createConfigurationContext(new Configuration());
+
+ assertTrue(context.isUiContext());
+ }
+
+ @Test
+ public void testIsUiContext_UiContextDerivedDisplayContext() {
+ final Context uiContext = getUiContext();
+ final Display secondaryDisplay =
+ getSecondaryDisplay(uiContext.getSystemService(DisplayManager.class));
+ final Context context = uiContext.createDisplayContext(secondaryDisplay);
+
+ assertFalse(context.isUiContext());
+ }
+
+ private Context getUiContext() {
+ final Context appContext = ApplicationProvider.getApplicationContext();
+ final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class);
+ final Display display = displayManager.getDisplay(DEFAULT_DISPLAY);
+ return appContext.createDisplayContext(display)
+ .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
}
}
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index af02b7b..de128ad 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -746,6 +746,20 @@
mController.onControlsChanged(createSingletonControl(ITYPE_IME));
assertEquals(newState.getSource(ITYPE_IME),
mTestHost.getModifiedState().peekSource(ITYPE_IME));
+
+ // The modified frames cannot be updated if there is an animation.
+ mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR));
+ mController.hide(navigationBars());
+ newState = new InsetsState(mController.getState(), true /* copySource */);
+ newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--;
+ mController.onStateChanged(newState);
+ assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
+ mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
+
+ // The modified frames can be updated while the animation is done.
+ mController.cancelExistingAnimations();
+ assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
+ mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
});
}
diff --git a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
index df2946c..c37a34a 100644
--- a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
+++ b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
@@ -201,6 +201,38 @@
}
@Test
+ public void testCursorDrag_diagonal_thresholdConfig() throws Throwable {
+ TextView tv = mActivity.findViewById(R.id.textview);
+ Editor editor = tv.getEditorForTesting();
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i <= 9; i++) {
+ sb.append("here is some text").append(i).append("\n");
+ }
+ sb.append(Strings.repeat("abcdefghij\n", 400)).append("Last");
+ String text = sb.toString();
+ onView(withId(R.id.textview)).perform(replaceText(text));
+
+ int index = text.indexOf("text9");
+ onView(withId(R.id.textview)).perform(clickOnTextAtIndex(index));
+ onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(index));
+
+ // Configure the drag direction threshold to require the drag to be exactly horizontal. With
+ // this set, a swipe that is slightly off horizontal should not trigger cursor drag.
+ editor.setCursorDragMinAngleFromVertical(90);
+ int startIdx = text.indexOf("5");
+ int endIdx = text.indexOf("here is some text3");
+ onView(withId(R.id.textview)).perform(dragOnText(startIdx, endIdx));
+ onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(index));
+
+ // Configure the drag direction threshold to require the drag to be 45 degrees or more from
+ // vertical. With this set, the same swipe gesture as above should now trigger cursor drag.
+ editor.setCursorDragMinAngleFromVertical(45);
+ onView(withId(R.id.textview)).perform(dragOnText(startIdx, endIdx));
+ onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(endIdx));
+ }
+
+ @Test
public void testCursorDrag_vertical_whenTextViewContentsFitOnScreen() throws Throwable {
String text = "012345_aaa\n"
+ "0123456789\n"
diff --git a/core/tests/coretests/src/android/widget/EditorTouchStateTest.java b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
index 35fd4bd..94f43de 100644
--- a/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
+++ b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
@@ -165,7 +165,7 @@
long event2Time = 1001;
MotionEvent event2 = moveEvent(event1Time, event2Time, 200f, 31f);
mTouchState.update(event2, mConfig);
- assertDrag(mTouchState, 20f, 30f, 0, 0, false);
+ assertDrag(mTouchState, 20f, 30f, 0, 0, 180f);
// Simulate an ACTION_UP event with a delay that's longer than the double-tap timeout.
long event3Time = 5000;
@@ -280,7 +280,7 @@
long event3Time = 1002;
MotionEvent event3 = moveEvent(event3Time, event3Time, newX, newY);
mTouchState.update(event3, mConfig);
- assertDrag(mTouchState, 20f, 30f, 0, 0, false);
+ assertDrag(mTouchState, 20f, 30f, 0, 0, Float.MAX_VALUE);
// Simulate an ACTION_UP event.
long event4Time = 1003;
@@ -301,15 +301,15 @@
long event2Time = 1002;
MotionEvent event2 = moveEvent(event1Time, event2Time, 100f, 174f);
mTouchState.update(event2, mConfig);
- assertDrag(mTouchState, 0f, 0f, 0, 0, true);
+ assertDrag(mTouchState, 0f, 0f, 0, 0, 100f / 174f);
// Simulate another ACTION_MOVE event that is horizontal from the original down event.
- // The value of `isDragCloseToVertical` should NOT change since it should only reflect the
- // initial direction of movement.
+ // The drag direction ratio should NOT change since it should only reflect the initial
+ // direction of movement.
long event3Time = 1003;
MotionEvent event3 = moveEvent(event1Time, event3Time, 200f, 0f);
mTouchState.update(event3, mConfig);
- assertDrag(mTouchState, 0f, 0f, 0, 0, true);
+ assertDrag(mTouchState, 0f, 0f, 0, 0, 100f / 174f);
// Simulate an ACTION_UP event.
long event4Time = 1004;
@@ -330,15 +330,15 @@
long event2Time = 1002;
MotionEvent event2 = moveEvent(event1Time, event2Time, 100f, 90f);
mTouchState.update(event2, mConfig);
- assertDrag(mTouchState, 0f, 0f, 0, 0, false);
+ assertDrag(mTouchState, 0f, 0f, 0, 0, 100f / 90f);
// Simulate another ACTION_MOVE event that is vertical from the original down event.
- // The value of `isDragCloseToVertical` should NOT change since it should only reflect the
- // initial direction of movement.
+ // The drag direction ratio should NOT change since it should only reflect the initial
+ // direction of movement.
long event3Time = 1003;
MotionEvent event3 = moveEvent(event1Time, event3Time, 0f, 200f);
mTouchState.update(event3, mConfig);
- assertDrag(mTouchState, 0f, 0f, 0, 0, false);
+ assertDrag(mTouchState, 0f, 0f, 0, 0, 100f / 90f);
// Simulate an ACTION_UP event.
long event4Time = 1004;
@@ -374,7 +374,7 @@
long event2Time = 1002;
MotionEvent event2 = moveEvent(event2Time, event2Time, 200f, 30f);
mTouchState.update(event2, mConfig);
- assertDrag(mTouchState, 20f, 30f, 0, 0, false);
+ assertDrag(mTouchState, 20f, 30f, 0, 0, Float.MAX_VALUE);
// Simulate an ACTION_CANCEL event.
long event3Time = 1003;
@@ -411,6 +411,84 @@
assertSingleTap(mTouchState, 22f, 33f, 20f, 30f);
}
+ @Test
+ public void testGetXYRatio() throws Exception {
+ doTestGetXYRatio(-1, 0.0f);
+ doTestGetXYRatio(0, 0.0f);
+ doTestGetXYRatio(30, 0.58f);
+ doTestGetXYRatio(45, 1.0f);
+ doTestGetXYRatio(60, 1.73f);
+ doTestGetXYRatio(90, Float.MAX_VALUE);
+ doTestGetXYRatio(91, Float.MAX_VALUE);
+ }
+
+ private void doTestGetXYRatio(int angleFromVerticalInDegrees, float expectedXYRatioRounded) {
+ float result = EditorTouchState.getXYRatio(angleFromVerticalInDegrees);
+ String msg = String.format(
+ "%d deg should give an x/y ratio of %f; actual unrounded result is %f",
+ angleFromVerticalInDegrees, expectedXYRatioRounded, result);
+ float roundedResult = (result == 0.0f || result == Float.MAX_VALUE) ? result :
+ Math.round(result * 100) / 100f;
+ assertThat(msg, roundedResult, is(expectedXYRatioRounded));
+ }
+
+ @Test
+ public void testUpdate_dragDirection() throws Exception {
+ // Simulate moving straight up.
+ doTestDragDirection(100f, 100f, 100f, 50f, 0f);
+
+ // Simulate moving straight down.
+ doTestDragDirection(100f, 100f, 100f, 150f, 0f);
+
+ // Simulate moving straight left.
+ doTestDragDirection(100f, 100f, 50f, 100f, Float.MAX_VALUE);
+
+ // Simulate moving straight right.
+ doTestDragDirection(100f, 100f, 150f, 100f, Float.MAX_VALUE);
+
+ // Simulate moving up and right, < 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 110f, 50f, 10f / 50f);
+
+ // Simulate moving up and right, > 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 150f, 90f, 50f / 10f);
+
+ // Simulate moving down and right, < 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 110f, 150f, 10f / 50f);
+
+ // Simulate moving down and right, > 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 150f, 110f, 50f / 10f);
+
+ // Simulate moving down and left, < 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 90f, 150f, 10f / 50f);
+
+ // Simulate moving down and left, > 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 50f, 110f, 50f / 10f);
+
+ // Simulate moving up and left, < 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 90f, 50f, 10f / 50f);
+
+ // Simulate moving up and left, > 45 deg from vertical.
+ doTestDragDirection(100f, 100f, 50f, 90f, 50f / 10f);
+ }
+
+ private void doTestDragDirection(float downX, float downY, float moveX, float moveY,
+ float expectedInitialDragDirectionXYRatio) {
+ EditorTouchState touchState = new EditorTouchState();
+
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1001;
+ MotionEvent event1 = downEvent(event1Time, event1Time, downX, downY);
+ touchState.update(event1, mConfig);
+
+ // Simulate an ACTION_MOVE event.
+ long event2Time = 1002;
+ MotionEvent event2 = moveEvent(event1Time, event2Time, moveX, moveY);
+ touchState.update(event2, mConfig);
+ String msg = String.format("(%.0f,%.0f)=>(%.0f,%.0f)", downX, downY, moveX, moveY);
+ assertThat(msg, touchState.getInitialDragDirectionXYRatio(),
+ is(expectedInitialDragDirectionXYRatio));
+ }
+
private static MotionEvent downEvent(long downTime, long eventTime, float x, float y) {
return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
}
@@ -441,7 +519,7 @@
}
private static void assertDrag(EditorTouchState touchState, float lastDownX,
- float lastDownY, float lastUpX, float lastUpY, boolean isDragCloseToVertical) {
+ float lastDownY, float lastUpX, float lastUpY, float initialDragDirectionXYRatio) {
assertThat(touchState.getLastDownX(), is(lastDownX));
assertThat(touchState.getLastDownY(), is(lastDownY));
assertThat(touchState.getLastUpX(), is(lastUpX));
@@ -451,7 +529,7 @@
assertThat(touchState.isMultiTap(), is(false));
assertThat(touchState.isMultiTapInSameArea(), is(false));
assertThat(touchState.isMovedEnoughForDrag(), is(true));
- assertThat(touchState.isDragCloseToVertical(), is(isDragCloseToVertical));
+ assertThat(touchState.getInitialDragDirectionXYRatio(), is(initialDragDirectionXYRatio));
}
private static void assertMultiTap(EditorTouchState touchState,
@@ -467,6 +545,5 @@
|| multiTapStatus == MultiTapStatus.TRIPLE_CLICK));
assertThat(touchState.isMultiTapInSameArea(), is(isMultiTapInSameArea));
assertThat(touchState.isMovedEnoughForDrag(), is(false));
- assertThat(touchState.isDragCloseToVertical(), is(false));
}
}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index ada8b00..06f1dae 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -35,6 +35,7 @@
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MASTER_CLEAR"/>
<permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
<permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 880c6f9..e08e42a 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -143,6 +143,7 @@
<permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<permission name="android.permission.PACKAGE_USAGE_STATS" />
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+ <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
<!-- For permission hub 2 debugging only -->
<permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
@@ -430,18 +431,6 @@
<permission name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<!-- Permissions required for CTS test - AdbManagerTest -->
<permission name="android.permission.MANAGE_DEBUGGING" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases, AtsCarDeviceApp -->
- <permission name="android.car.permission.CAR_DRIVING_STATE" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo, AtsAudioDeviceTestCases -->
- <permission name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo -->
- <permission name="android.car.permission.CAR_DIAGNOSTICS" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo -->
- <permission name="android.car.permission.CLEAR_CAR_DIAGNOSTICS" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases -->
- <permission name="android.car.permission.CONTROL_APP_BLOCKING" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases -->
- <permission name="android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt
index d8af726..70dedb8 100644
--- a/framework-jarjar-rules.txt
+++ b/framework-jarjar-rules.txt
@@ -1,2 +1,6 @@
rule android.hidl.** android.internal.hidl.@1
rule android.net.wifi.WifiAnnotations* android.internal.wifi.WifiAnnotations@1
+
+# Hide media mainline module implementation classes to avoid collisions with
+# app-bundled ExoPlayer classes.
+rule com.google.android.exoplayer2.** android.media.internal.exo.@1
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index d25fc4b..b2c39c9 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -139,6 +139,9 @@
(*mGlobalData)->reportJank();
}
+ if (mSwapDeadline < 0) {
+ mSwapDeadline = frame[FrameInfoIndex::IntendedVsync] + mFrameInterval;
+ }
bool isTripleBuffered = (mSwapDeadline - frame[FrameInfoIndex::IntendedVsync]) > (mFrameInterval * 0.1);
mSwapDeadline = std::max(mSwapDeadline + mFrameInterval,
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 4460266..b3fbbfe 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -75,7 +75,7 @@
std::array<int64_t, NUM_BUCKETS> mThresholds;
int64_t mFrameInterval;
- nsecs_t mSwapDeadline;
+ nsecs_t mSwapDeadline = -1;
// The amount of time we will erase from the total duration to account
// for SF vsync offsets with HWC2 blocking dequeueBuffers.
// (Vsync + mDequeueBlockTolerance) is the point at which we expect
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 5e0471c..7982ab6 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -208,8 +208,12 @@
return config;
}
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+
void EglManager::initExtensions() {
auto extensions = StringUtils::split(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+ auto extensionsAndroid =
+ StringUtils::split(eglQueryStringImplementationANDROID(mEglDisplay, EGL_EXTENSIONS));
// For our purposes we don't care if EGL_BUFFER_AGE is a result of
// EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
@@ -228,9 +232,12 @@
EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough");
EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
- EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync");
EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync");
EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync");
+
+ // EGL_ANDROID_native_fence_sync is not exposed to applications, so access
+ // this through the private Android-specific query instead.
+ EglExtensions.nativeFenceSync = extensionsAndroid.has("EGL_ANDROID_native_fence_sync");
}
bool EglManager::hasEglContext() {
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index 644d5fb..e419801 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -559,6 +559,7 @@
AStatsEvent_writeBool(event, !lastFullDay);
AStatsEvent_build(event);
}
+ delete dump;
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 2a2aaea..05a9863 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -3039,7 +3039,7 @@
protected GnssRequest merge(@NonNull List<GnssRequest> requests) {
Preconditions.checkArgument(!requests.isEmpty());
for (GnssRequest request : requests) {
- if (request.isFullTracking()) {
+ if (request != null && request.isFullTracking()) {
return request;
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index ccf078b..b3102e24 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -21,6 +21,8 @@
import com.android.systemui.car.navigationbar.CarNavigationBar;
import com.android.systemui.car.notification.CarNotificationModule;
import com.android.systemui.car.sideloaded.SideLoadedAppController;
+import com.android.systemui.car.statusbar.UnusedStatusBar;
+import com.android.systemui.car.statusbar.UnusedStatusBarModule;
import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier;
import com.android.systemui.car.volume.VolumeUI;
import com.android.systemui.car.window.OverlayWindowModule;
@@ -34,7 +36,6 @@
import com.android.systemui.recents.RecentsModule;
import com.android.systemui.shortcut.ShortcutKeyDispatcher;
import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.notification.InstantAppNotifier;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -48,9 +49,9 @@
import dagger.multibindings.IntoMap;
/** Binder for car specific {@link SystemUI} modules. */
-@Module(includes = {RecentsModule.class, StatusBarModule.class, NotificationsModule.class,
+@Module(includes = {RecentsModule.class, NotificationsModule.class,
BubbleModule.class, KeyguardModule.class, OverlayWindowModule.class,
- CarNotificationModule.class})
+ CarNotificationModule.class, UnusedStatusBarModule.class})
public abstract class CarSystemUIBinder {
/** Inject into AuthController. */
@Binds
@@ -153,7 +154,7 @@
@Binds
@IntoMap
@ClassKey(StatusBar.class)
- public abstract SystemUI bindsStatusBar(StatusBar sysui);
+ public abstract SystemUI bindsStatusBar(UnusedStatusBar sysui);
/** Inject into VolumeUI. */
@Binds
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index cde3699f..0e3c7f3 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -30,6 +30,7 @@
import com.android.systemui.car.keyguard.CarKeyguardViewController;
import com.android.systemui.car.statusbar.DozeServiceHost;
import com.android.systemui.car.statusbar.DummyNotificationShadeWindowController;
+import com.android.systemui.car.statusbar.UnusedStatusBar;
import com.android.systemui.car.volume.CarVolumeDialogComponent;
import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.dagger.qualifiers.Background;
@@ -57,6 +58,7 @@
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.ShadeControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -175,4 +177,7 @@
@Binds
abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost);
+
+ @Binds
+ abstract StatusBar bindStatusBar(UnusedStatusBar statusBar);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
index 8d58436..a7cb0d8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
@@ -91,7 +91,6 @@
private RecyclerView mNotificationList;
private NotificationViewController mNotificationViewController;
- private boolean mIsTracking;
private boolean mNotificationListAtEnd;
private float mFirstTouchDownOnGlassPane;
private boolean mNotificationListAtEndAtTimeOfTouch;
@@ -299,14 +298,14 @@
// The glass pane is used to view touch events before passed to the notification list.
// This allows us to initialize gesture listeners and detect when to close the notifications
glassPane.setOnTouchListener((v, event) -> {
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (isClosingAction(event)) {
mNotificationListAtEndAtTimeOfTouch = false;
}
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ if (isOpeningAction(event)) {
mFirstTouchDownOnGlassPane = event.getRawX();
mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd;
// Reset the tracker when there is a touch down on the glass pane.
- mIsTracking = false;
+ setIsTracking(false);
// Pass the down event to gesture detector so that it knows where the touch event
// started.
closeGestureDetector.onTouchEvent(event);
@@ -341,22 +340,21 @@
// If the card is swiping we should not allow the notification shade to close.
// Hence setting mNotificationListAtEndAtTimeOfTouch to false will stop that
- // for us. We are also checking for mIsTracking because while swiping the
+ // for us. We are also checking for isTracking() because while swiping the
// notification shade to close if the user goes a bit horizontal while swiping
// upwards then also this should close.
- if (mIsNotificationCardSwiping && !mIsTracking) {
+ if (mIsNotificationCardSwiping && !isTracking()) {
mNotificationListAtEndAtTimeOfTouch = false;
}
boolean handled = closeGestureDetector.onTouchEvent(event);
- boolean isTracking = mIsTracking;
+ boolean isTracking = isTracking();
Rect rect = getLayout().getClipBounds();
float clippedHeight = 0;
if (rect != null) {
clippedHeight = rect.bottom;
}
- if (!handled && event.getActionMasked() == MotionEvent.ACTION_UP
- && mIsSwipingVerticallyToClose) {
+ if (!handled && isClosingAction(event) && mIsSwipingVerticallyToClose) {
if (getSettleClosePercentage() < getPercentageFromEndingEdge() && isTracking) {
animatePanel(DEFAULT_FLING_VELOCITY, false);
} else if (clippedHeight != getLayout().getHeight() && isTracking) {
@@ -369,7 +367,7 @@
// Updating the mNotificationListAtEndAtTimeOfTouch state has to be done after
// the event has been passed to the closeGestureDetector above, such that the
// closeGestureDetector sees the up event before the state has changed.
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (isClosingAction(event)) {
mNotificationListAtEndAtTimeOfTouch = false;
}
return handled || isTracking;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java
new file mode 100644
index 0000000..48334bd
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java
@@ -0,0 +1,224 @@
+/*
+ * 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.car.statusbar;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.util.DisplayMetrics;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.InitController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.PluginDependencyProvider;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
+import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
+import com.android.systemui.statusbar.phone.LockscreenLockIconController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NavigationBarView;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.volume.VolumeComponent;
+
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import javax.inject.Provider;
+
+import dagger.Lazy;
+
+/** Unused variant of {@link StatusBar} specifically used in the automotive context. */
+public class UnusedStatusBar extends StatusBar {
+
+ public UnusedStatusBar(Context context,
+ NotificationsController notificationsController,
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationInterruptStateProvider notificationInterruptStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ KeyguardViewMediator keyguardViewMediator,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ Executor uiBgExecutor,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ Lazy<AssistManager> assistManagerLazy,
+ ConfigurationController configurationController,
+ NotificationShadeWindowController notificationShadeWindowController,
+ LockscreenLockIconController lockscreenLockIconController,
+ DozeParameters dozeParameters,
+ ScrimController scrimController,
+ KeyguardLiftController keyguardLiftController,
+ Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+ Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+ DozeServiceHost dozeServiceHost,
+ PowerManager powerManager,
+ ScreenPinningRequest screenPinningRequest,
+ DozeScrimController dozeScrimController,
+ VolumeComponent volumeComponent,
+ CommandQueue commandQueue,
+ Optional<Recents> recentsOptional,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
+ PluginManager pluginManager,
+ Optional<Divider> dividerOptional,
+ LightsOutNotifController lightsOutNotifController,
+ StatusBarNotificationActivityStarter.Builder statusBarNotifActivityStarterBuilder,
+ ShadeController shadeController,
+ SuperStatusBarViewFactory superStatusBarViewFactory,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ InitController initController,
+ DarkIconDispatcher darkIconDispatcher,
+ Handler timeTickHandler,
+ PluginDependencyProvider pluginDependencyProvider,
+ KeyguardDismissUtil keyguardDismissUtil,
+ ExtensionController extensionController,
+ UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
+ KeyguardIndicationController keyguardIndicationController,
+ DismissCallbackRegistry dismissCallbackRegistry,
+ Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ super(context, notificationsController, lightBarController, autoHideController,
+ keyguardUpdateMonitor, statusBarIconController, pulseExpansionHandler,
+ notificationWakeUpCoordinator, keyguardBypassController, keyguardStateController,
+ headsUpManagerPhone, dynamicPrivacyController, bypassHeadsUpNotifier,
+ falsingManager,
+ broadcastDispatcher, remoteInputQuickSettingsDisabler, notificationGutsManager,
+ notificationLogger, notificationInterruptStateProvider,
+ notificationViewHierarchyManager, keyguardViewMediator, displayMetrics,
+ metricsLogger,
+ uiBgExecutor, notificationMediaManager, lockScreenUserManager, remoteInputManager,
+ userSwitcherController, networkController, batteryController, colorExtractor,
+ screenLifecycle, wakefulnessLifecycle, statusBarStateController, vibratorHelper,
+ bubbleController, groupManager, visualStabilityManager, deviceProvisionedController,
+ navigationBarController, assistManagerLazy, configurationController,
+ notificationShadeWindowController, lockscreenLockIconController, dozeParameters,
+ scrimController, keyguardLiftController, lockscreenWallpaperLazy,
+ biometricUnlockControllerLazy, dozeServiceHost, powerManager, screenPinningRequest,
+ dozeScrimController, volumeComponent, commandQueue, recentsOptional,
+ statusBarComponentBuilder, pluginManager, dividerOptional, lightsOutNotifController,
+ statusBarNotifActivityStarterBuilder, shadeController, superStatusBarViewFactory,
+ statusBarKeyguardViewManager, viewMediatorCallback, initController,
+ darkIconDispatcher,
+ timeTickHandler, pluginDependencyProvider, keyguardDismissUtil, extensionController,
+ userInfoControllerImpl, phoneStatusBarPolicy, keyguardIndicationController,
+ dismissCallbackRegistry, notificationShadeDepthControllerLazy,
+ statusBarTouchableRegionManager);
+ }
+
+ @Override
+ public void notifyBiometricAuthModeChanged() {
+ // No-op for Automotive devices.
+ }
+
+ @Override
+ public NavigationBarView getNavigationBarView() {
+ // Return null for Automotive devices.
+ return null;
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java
new file mode 100644
index 0000000..2c86e4d
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java
@@ -0,0 +1,285 @@
+/*
+ * 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.car.statusbar;
+
+import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.util.DisplayMetrics;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.InitController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.PluginDependencyProvider;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.dagger.StatusBarDependenciesModule;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
+import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.NotificationRowModule;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
+import com.android.systemui.statusbar.phone.LockscreenLockIconController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneDependenciesModule;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.volume.VolumeComponent;
+
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger Module providing {@link UnusedStatusBar}.
+ */
+@Module(includes = {StatusBarDependenciesModule.class, StatusBarPhoneDependenciesModule.class,
+ NotificationRowModule.class})
+public interface UnusedStatusBarModule {
+ /**
+ * Provides our instance of StatusBar which is considered optional.
+ */
+ @Provides
+ @Singleton
+ static UnusedStatusBar provideStatusBar(
+ Context context,
+ NotificationsController notificationsController,
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationInterruptStateProvider notificationInterruptStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ KeyguardViewMediator keyguardViewMediator,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ @UiBackground Executor uiBgExecutor,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ Lazy<AssistManager> assistManagerLazy,
+ ConfigurationController configurationController,
+ NotificationShadeWindowController notificationShadeWindowController,
+ LockscreenLockIconController lockscreenLockIconController,
+ DozeParameters dozeParameters,
+ ScrimController scrimController,
+ @Nullable KeyguardLiftController keyguardLiftController,
+ Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+ Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+ DozeServiceHost dozeServiceHost,
+ PowerManager powerManager,
+ ScreenPinningRequest screenPinningRequest,
+ DozeScrimController dozeScrimController,
+ VolumeComponent volumeComponent,
+ CommandQueue commandQueue,
+ Optional<Recents> recentsOptional,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
+ PluginManager pluginManager,
+ Optional<Divider> dividerOptional,
+ LightsOutNotifController lightsOutNotifController,
+ StatusBarNotificationActivityStarter.Builder
+ statusBarNotificationActivityStarterBuilder,
+ ShadeController shadeController,
+ SuperStatusBarViewFactory superStatusBarViewFactory,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ InitController initController,
+ DarkIconDispatcher darkIconDispatcher,
+ @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
+ PluginDependencyProvider pluginDependencyProvider,
+ KeyguardDismissUtil keyguardDismissUtil,
+ ExtensionController extensionController,
+ UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
+ KeyguardIndicationController keyguardIndicationController,
+ Lazy<NotificationShadeDepthController> notificationShadeDepthController,
+ DismissCallbackRegistry dismissCallbackRegistry,
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ return new UnusedStatusBar(
+ context,
+ notificationsController,
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationInterruptStateProvider,
+ notificationViewHierarchyManager,
+ keyguardViewMediator,
+ displayMetrics,
+ metricsLogger,
+ uiBgExecutor,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManagerLazy,
+ configurationController,
+ notificationShadeWindowController,
+ lockscreenLockIconController,
+ dozeParameters,
+ scrimController,
+ keyguardLiftController,
+ lockscreenWallpaperLazy,
+ biometricUnlockControllerLazy,
+ dozeServiceHost,
+ powerManager,
+ screenPinningRequest,
+ dozeScrimController,
+ volumeComponent,
+ commandQueue,
+ recentsOptional,
+ statusBarComponentBuilder,
+ pluginManager,
+ dividerOptional,
+ lightsOutNotifController,
+ statusBarNotificationActivityStarterBuilder,
+ shadeController,
+ superStatusBarViewFactory,
+ statusBarKeyguardViewManager,
+ viewMediatorCallback,
+ initController,
+ darkIconDispatcher,
+ timeTickHandler,
+ pluginDependencyProvider,
+ keyguardDismissUtil,
+ extensionController,
+ userInfoControllerImpl,
+ phoneStatusBarPolicy,
+ keyguardIndicationController,
+ dismissCallbackRegistry,
+ notificationShadeDepthController,
+ statusBarTouchableRegionManager);
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
index 45808a8..1b00c63 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
@@ -191,6 +191,38 @@
}
}
+ /** Checks if a {@link MotionEvent} is an action to open the panel.
+ * @param e {@link MotionEvent} to check.
+ * @return true only if opening action.
+ */
+ protected boolean isOpeningAction(MotionEvent e) {
+ if (mAnimateDirection == POSITIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ if (mAnimateDirection == NEGATIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ return false;
+ }
+
+ /** Checks if a {@link MotionEvent} is an action to close the panel.
+ * @param e {@link MotionEvent} to check.
+ * @return true only if closing action.
+ */
+ protected boolean isClosingAction(MotionEvent e) {
+ if (mAnimateDirection == POSITIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ if (mAnimateDirection == NEGATIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ return false;
+ }
+
/* ***************************************************************************************** *
* Panel Animation
* ***************************************************************************************** */
@@ -243,8 +275,7 @@
* Depending on certain conditions, determines whether to fully expand or collapse the panel.
*/
protected void maybeCompleteAnimation(MotionEvent event) {
- if (event.getActionMasked() == MotionEvent.ACTION_UP
- && isPanelVisible()) {
+ if (isClosingAction(event) && isPanelVisible()) {
if (mSettleClosePercentage < mPercentageFromEndingEdge) {
animatePanel(DEFAULT_FLING_VELOCITY, false);
} else {
@@ -266,14 +297,17 @@
float from = getCurrentStartPosition(rect);
if (from != to) {
animate(from, to, velocity, isClosing);
- return;
}
+
+ // If we swipe down the notification panel all the way to the bottom of the screen
+ // (i.e. from == to), then we have finished animating the panel.
+ return;
}
// We will only be here if the shade is being opened programmatically or via button when
// height of the layout was not calculated.
- ViewTreeObserver notificationTreeObserver = getLayout().getViewTreeObserver();
- notificationTreeObserver.addOnGlobalLayoutListener(
+ ViewTreeObserver panelTreeObserver = getLayout().getViewTreeObserver();
+ panelTreeObserver.addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
@@ -476,6 +510,11 @@
return mIsTracking;
}
+ /** Sets whether the panel is currently tracking or not. */
+ protected final void setIsTracking(boolean isTracking) {
+ mIsTracking = isTracking;
+ }
+
/** Returns {@code true} if the panel is currently animating. */
protected final boolean isAnimating() {
return mIsAnimating;
@@ -514,7 +553,7 @@
}
setPanelVisible(true);
- // clips the view for the notification shade when the user scrolls to open.
+ // clips the view for the panel when the user scrolls to open.
setViewClipBounds((int) event2.getRawY());
// Initially the scroll starts with height being zero. This checks protects from divide
@@ -569,11 +608,11 @@
boolean isInClosingDirection = mAnimateDirection * distanceY > 0;
// This check is to figure out if onScroll was called while swiping the card at
- // bottom of the list. At that time we should not allow notification shade to
+ // bottom of the panel. At that time we should not allow panel to
// close. We are also checking for the upwards swipe gesture here because it is
- // possible if a user is closing the notification shade and while swiping starts
+ // possible if a user is closing the panel and while swiping starts
// to open again but does not fling. At that time we should allow the
- // notification shade to close fully or else it would stuck in between.
+ // panel to close fully or else it would stuck in between.
if (Math.abs(getLayout().getHeight() - y)
> SWIPE_DOWN_MIN_DISTANCE && isInClosingDirection) {
setViewClipBounds((int) y);
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index f42bf19..11d1b0a 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -483,6 +483,13 @@
}
@Override
+ protected void onDocIdDeleted(String docId) {
+ Uri uri = DocumentsContract.buildDocumentUri(AUTHORITY, docId);
+ getContext().revokeUriPermission(uri, ~0);
+ }
+
+
+ @Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
synchronized (mRootsLock) {
diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml
index a93fceb..b6b287f 100644
--- a/packages/PrintSpooler/res/values-as/strings.xml
+++ b/packages/PrintSpooler/res/values-as/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDFৰ জৰিয়তে ছেভ কৰক"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ’ল"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ’ল"</string>
- <string name="search" msgid="5421724265322228497">"সন্ধান কৰক"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
<string name="all_printers_label" msgid="3178848870161526399">"সকলো প্ৰিণ্টাৰ"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"সেৱা যোগ কৰক"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সন্ধান বাকচটো দেখুওৱা হ’ল"</string>
diff --git a/packages/PrintSpooler/res/values-bn/strings.xml b/packages/PrintSpooler/res/values-bn/strings.xml
index 637becb..b2e1eed 100644
--- a/packages/PrintSpooler/res/values-bn/strings.xml
+++ b/packages/PrintSpooler/res/values-bn/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"পিডিএফ হিসাবে সেভ করুন"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"প্রিন্ট বিকল্প প্রসারিত হয়েছে"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"প্রিন্ট বিকল্প সংকুচিত হয়েছে"</string>
- <string name="search" msgid="5421724265322228497">"খুঁজুন"</string>
+ <string name="search" msgid="5421724265322228497">"সার্চ"</string>
<string name="all_printers_label" msgid="3178848870161526399">"সমস্ত প্রিন্টার"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"পরিষেবা যোগ করুন"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সার্চ বাক্স দেখানো হচ্ছে"</string>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 596947d..719fc92 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -31,7 +31,7 @@
<string name="template_all_pages" msgid="3322235982020148762">"همه <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="template_page_range" msgid="428638530038286328">"محدوده <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="pages_range_example" msgid="8558694453556945172">"مثلاً ۱—۵،۹،۷—۱۰"</string>
- <string name="print_preview" msgid="8010217796057763343">"پیشنمایش چاپ"</string>
+ <string name="print_preview" msgid="8010217796057763343">"پیشنمای چاپ"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"نصب نمایشگر PDF برای پیشنمایش"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"برنامه چاپ خراب شد"</string>
<string name="generating_print_job" msgid="3119608742651698916">"در حال ایجاد کار چاپ"</string>
diff --git a/packages/PrintSpooler/res/values-kn/strings.xml b/packages/PrintSpooler/res/values-kn/strings.xml
index 150ede4..261fe4b 100644
--- a/packages/PrintSpooler/res/values-kn/strings.xml
+++ b/packages/PrintSpooler/res/values-kn/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF ಗೆ ಉಳಿಸು"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
- <string name="search" msgid="5421724265322228497">"ಹುಡುಕಿ"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
<string name="all_printers_label" msgid="3178848870161526399">"ಎಲ್ಲಾ ಪ್ರಿಂಟರ್ಗಳು"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ಸೇವೆಯನ್ನು ಸೇರಿಸು"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯನ್ನು ತೋರಿಸಲಾಗಿದೆ"</string>
diff --git a/packages/PrintSpooler/res/values-ml/strings.xml b/packages/PrintSpooler/res/values-ml/strings.xml
index dbcd34b..73af95d 100644
--- a/packages/PrintSpooler/res/values-ml/strings.xml
+++ b/packages/PrintSpooler/res/values-ml/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF-ൽ സംരക്ഷിക്കുക"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ വിപുലീകരിച്ചു"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ ചുരുക്കി"</string>
- <string name="search" msgid="5421724265322228497">"തിരയൽ"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
<string name="all_printers_label" msgid="3178848870161526399">"എല്ലാ പ്രിന്ററുകളും"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"സേവനം ചേർക്കുക"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"തിരയൽ ബോക്സ് ദൃശ്യമാക്കിയിരിക്കുന്നു"</string>
diff --git a/packages/PrintSpooler/res/values-mr/strings.xml b/packages/PrintSpooler/res/values-mr/strings.xml
index 44456b4..4d7e919 100644
--- a/packages/PrintSpooler/res/values-mr/strings.xml
+++ b/packages/PrintSpooler/res/values-mr/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"पीडीएफ वर सेव्ह करा"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"प्रिंट पर्याय विस्तृत झाले"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"प्रिंट पर्याय संक्षिप्त झाले"</string>
- <string name="search" msgid="5421724265322228497">"शोध"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
<string name="all_printers_label" msgid="3178848870161526399">"सर्व प्रिंटर"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"सेवा जोडा"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"शोध बॉक्स दर्शविला"</string>
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
index a1675fa..7000b95 100644
--- a/packages/PrintSpooler/res/values-or/strings.xml
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDFରେ ସେଭ୍ କରନ୍ତୁ"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି"</string>
- <string name="search" msgid="5421724265322228497">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
<string name="all_printers_label" msgid="3178848870161526399">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଗ କରନ୍ତୁ"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି"</string>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index b01b50a..79944bb 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF వలె సేవ్ చేయి"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
- <string name="search" msgid="5421724265322228497">"వెతుకు"</string>
+ <string name="search" msgid="5421724265322228497">"సెర్చ్"</string>
<string name="all_printers_label" msgid="3178848870161526399">"అన్ని ప్రింటర్లు"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించు"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"శోధన పెట్టె చూపబడింది"</string>
diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml
index d17bce7..ea0a6ea 100644
--- a/packages/PrintSpooler/res/values-uz/strings.xml
+++ b/packages/PrintSpooler/res/values-uz/strings.xml
@@ -100,7 +100,7 @@
</string-array>
<string-array name="orientation_labels">
<item msgid="4061931020926489228">"Tik holat"</item>
- <item msgid="3199660090246166812">"Eniga"</item>
+ <item msgid="3199660090246166812">"Yotiq"</item>
</string-array>
<string name="print_write_error_message" msgid="5787642615179572543">"Faylga yozib bo‘lmadi"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"Xatolik yuz berdi. Qaytadan urining."</string>
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 1e4c7ca..52d2b3c 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -376,8 +376,12 @@
* Check whether tile only has primary profile.
*/
public boolean isPrimaryProfileOnly() {
- String profile = mMetaData != null
- ? mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
+ return isPrimaryProfileOnly(mMetaData);
+ }
+
+ static boolean isPrimaryProfileOnly(Bundle metaData) {
+ String profile = metaData != null
+ ? metaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
profile = (profile != null ? profile : PROFILE_ALL);
return TextUtils.equals(profile, PROFILE_PRIMARY);
}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index ace50f3..49f6bd8 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -339,6 +339,16 @@
private static void loadTile(UserHandle user, Map<Pair<String, String>, Tile> addedCache,
String defaultCategory, List<Tile> outTiles, Intent intent, Bundle metaData,
ComponentInfo componentInfo) {
+ // Skip loading tile if the component is tagged primary_profile_only but not running on
+ // the current user.
+ if (user.getIdentifier() != ActivityManager.getCurrentUser()
+ && Tile.isPrimaryProfileOnly(componentInfo.metaData)) {
+ Log.w(LOG_TAG, "Found " + componentInfo.name + " for intent "
+ + intent + " is primary profile only, skip loading tile for uid "
+ + user.getIdentifier());
+ return;
+ }
+
String categoryKey = defaultCategory;
// Load category
if ((metaData == null || !metaData.containsKey(EXTRA_CATEGORY_KEY))
diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml
new file mode 100644
index 0000000..16e9190
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml
@@ -0,0 +1,31 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml
new file mode 100644
index 0000000..4c338c9
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2.01C7.25,2.01 2.97,4.09 0,7.4L7.582,16.625C7.582,16.627 7.58,16.629 7.58,16.631L11.99,22L12,22L13,20.789L13,17.641L13,13.119C12.68,13.039 12.34,13 12,13C10.601,13 9.351,13.64 8.531,14.639L2.699,7.539C5.269,5.279 8.58,4.01 12,4.01C15.42,4.01 18.731,5.279 21.301,7.539L16.811,13L19.4,13L24,7.4C21.03,4.09 16.75,2.01 12,2.01z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml
new file mode 100644
index 0000000..79037db
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C7.25,2 2.97,4.081 0,7.391L12,22L13,20.779L13,17.631L13,13L16.801,13L18,13L19.391,13L24,7.391C21.03,4.081 16.75,2 12,2zM12,4C14.747,4 17.423,4.819 19.701,6.313C20.259,6.678 20.795,7.085 21.301,7.529L17.389,12.287C16.029,10.868 14.119,9.99 12,9.99C9.88,9.99 7.969,10.869 6.609,12.289L2.699,7.529C5.269,5.269 8.58,4 12,4z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml
new file mode 100644
index 0000000..21ad128
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C7.25,2 2.97,4.081 0,7.391L3.301,11.41L12,22L13,20.779L13,17.631L13,13L16.801,13L19.391,13L20.699,11.41C20.699,11.409 20.698,11.409 20.697,11.408L24,7.391C21.03,4.081 16.75,2 12,2zM12,4C15.42,4 18.731,5.269 21.301,7.529L19.35,9.9C17.43,8.1 14.86,6.99 12,6.99C9.14,6.99 6.57,8.1 4.65,9.9C4.65,9.901 4.649,9.902 4.648,9.902L2.699,7.529C5.269,5.269 8.58,4 12,4z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml
new file mode 100644
index 0000000..2ec5ba3
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C7.25,2 2.97,4.08 0,7.39L12,22l1,-1.22V13h6.39L24,7.39C21.03,4.08 16.75,2 12,2z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
+</vector>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index f3b22d3..5fc311a 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -139,7 +139,7 @@
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"قدرت سیگنال Wi‑Fi کامل است."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"شبکه باز"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"شبکه ایمن"</string>
- <string name="process_kernel_label" msgid="950292573930336765">"سیستم عامل Android"</string>
+ <string name="process_kernel_label" msgid="950292573930336765">"سیستمعامل Android"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"برنامههای حذف شده"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"برنامهها و کاربران حذف شده"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"بهروزرسانیهای سیستم"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ddf2bc0..5f5be97 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -165,7 +165,7 @@
<string name="tts_lang_not_selected" msgid="7927823081096056147">"Langue non sélectionnée"</string>
<string name="tts_default_lang_summary" msgid="9042620014800063470">"Définir la langue utilisée par la synthèse vocale"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"Écouter un échantillon"</string>
- <string name="tts_play_example_summary" msgid="634044730710636383">"Lire une courte démonstration de la synthèse vocale"</string>
+ <string name="tts_play_example_summary" msgid="634044730710636383">"Écoutez une courte démonstration de la synthèse vocale"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"Installer les données vocales"</string>
<string name="tts_install_data_summary" msgid="3608874324992243851">"Installer les données nécessaires à la synthèse vocale"</string>
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Ce moteur de synthèse vocale est susceptible de collecter tout ce qui sera lu, y compris les données personnelles comme les mots de passe et les numéros de carte de paiement. Il provient du moteur <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Voulez-vous activer son utilisation ?"</string>
@@ -189,8 +189,8 @@
<item msgid="1158955023692670059">"Rapide"</item>
<item msgid="5664310435707146591">"Plus rapide"</item>
<item msgid="5491266922147715962">"Très rapide"</item>
- <item msgid="7659240015901486196">"Rapide"</item>
- <item msgid="7147051179282410945">"Très rapide"</item>
+ <item msgid="7659240015901486196">"Beaucoup plus rapide"</item>
+ <item msgid="7147051179282410945">"Extrêmement rapide"</item>
<item msgid="581904787661470707">"La plus rapide"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Sélectionner un profil"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index f219d24..8b92640 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -37,7 +37,7 @@
<string name="wifi_no_internet" msgid="1774198889176926299">"Ինտերնետ կապ չկա"</string>
<string name="saved_network" msgid="7143698034077223645">"Ով է պահել՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
- <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով"</string>
+ <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով"</string>
<string name="connected_via_passpoint" msgid="7735442932429075684">"Միացված է %1$s-ի միջոցով"</string>
<string name="connected_via_app" msgid="3532267661404276584">"Միացված է <xliff:g id="NAME">%1$s</xliff:g>-ի միջոցով"</string>
<string name="available_via_passpoint" msgid="1716000261192603682">"Հասանելի է %1$s-ի միջոցով"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 37cf189f..3ab50cc 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -31,7 +31,7 @@
<item msgid="7852381437933824454">"Memutus sambungan..."</item>
<item msgid="5046795712175415059">"Sambungan terputus"</item>
<item msgid="2473654476624070462">"Gagal"</item>
- <item msgid="9146847076036105115">"Dicekal"</item>
+ <item msgid="9146847076036105115">"Diblokir"</item>
<item msgid="4543924085816294893">"Menghindari sambungan buruk untuk sementara"</item>
</string-array>
<string-array name="wifi_status_with_ssid">
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 83b72e9..27f5dc9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -93,8 +93,8 @@
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Sim-toegang"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Gehoorapparaten"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met gehoorapparaten"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hoortoestellen"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met hoortoestellen"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbonden met audio van medium"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Verbonden met audio van telefoon"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Verbonden met server voor bestandsoverdracht"</string>
@@ -111,7 +111,7 @@
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Gebruiken voor audio van telefoon"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gebruiken voor bestandsoverdracht"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gebruiken voor invoer"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruiken voor gehoorapparaten"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruiken voor hoortoestellen"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koppelen"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOPPELEN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuleren"</string>
@@ -127,8 +127,8 @@
<string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Hoofdtelefoon"</string>
<string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Randapparaat voor invoer"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
- <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Linker gehoorapparaat koppelen…"</string>
- <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Rechter gehoorapparaat koppelen…"</string>
+ <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Linker hoortoestel koppelen…"</string>
+ <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Rechter hoortoestel koppelen…"</string>
<string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Links: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"Rechts: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="accessibility_wifi_off" msgid="1195445715254137155">"Wifi: uitgeschakeld."</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index a43412e..b280806 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -49,11 +49,19 @@
private static String sSharedSystemSharedLibPackageName;
static final int[] WIFI_PIE = {
- com.android.internal.R.drawable.ic_wifi_signal_0,
- com.android.internal.R.drawable.ic_wifi_signal_1,
- com.android.internal.R.drawable.ic_wifi_signal_2,
- com.android.internal.R.drawable.ic_wifi_signal_3,
- com.android.internal.R.drawable.ic_wifi_signal_4
+ com.android.internal.R.drawable.ic_wifi_signal_0,
+ com.android.internal.R.drawable.ic_wifi_signal_1,
+ com.android.internal.R.drawable.ic_wifi_signal_2,
+ com.android.internal.R.drawable.ic_wifi_signal_3,
+ com.android.internal.R.drawable.ic_wifi_signal_4
+ };
+
+ static final int[] SHOW_X_WIFI_PIE = {
+ R.drawable.ic_show_x_wifi_signal_0,
+ R.drawable.ic_show_x_wifi_signal_1,
+ R.drawable.ic_show_x_wifi_signal_2,
+ R.drawable.ic_show_x_wifi_signal_3,
+ R.drawable.ic_show_x_wifi_signal_4
};
public static void updateLocationEnabled(Context context, boolean enabled, int userId,
@@ -353,10 +361,22 @@
* @throws IllegalArgumentException if an invalid RSSI level is given.
*/
public static int getWifiIconResource(int level) {
+ return getWifiIconResource(false /* showX */, level);
+ }
+
+ /**
+ * Returns the Wifi icon resource for a given RSSI level.
+ *
+ * @param showX True if a connected Wi-Fi network has the problem which should show Pie+x
+ * signal icon to users.
+ * @param level The number of bars to show (0-4)
+ * @throws IllegalArgumentException if an invalid RSSI level is given.
+ */
+ public static int getWifiIconResource(boolean showX, int level) {
if (level < 0 || level >= WIFI_PIE.length) {
throw new IllegalArgumentException("No Wifi icon found for level: " + level);
}
- return WIFI_PIE[level];
+ return showX ? SHOW_X_WIFI_PIE[level] : WIFI_PIE[level];
}
public static int getDefaultStorageManagerDaysToRetain(Resources resources) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java
index a53bc9f..bba69f2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java
@@ -35,6 +35,7 @@
import com.android.settingslib.R;
import com.android.settingslib.Utils;
import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectedInfo;
/**
* Preference to display a WifiEntry in a wifi picker.
@@ -64,6 +65,7 @@
private final IconInjector mIconInjector;
private WifiEntry mWifiEntry;
private int mLevel = -1;
+ private boolean mShowX; // Shows the Wi-Fi signl icon of Pie+x when it's true.
private CharSequence mContentDescription;
private OnButtonClickListener mOnButtonClickListener;
@@ -136,9 +138,15 @@
public void refresh() {
setTitle(mWifiEntry.getTitle());
final int level = mWifiEntry.getLevel();
- if (level != mLevel) {
+ final ConnectedInfo connectedInfo = mWifiEntry.getConnectedInfo();
+ boolean showX = false;
+ if (connectedInfo != null) {
+ showX = !connectedInfo.isDefaultNetwork || !connectedInfo.isValidated;
+ }
+ if (level != mLevel || showX != mShowX) {
mLevel = level;
- updateIcon(mLevel);
+ mShowX = showX;
+ updateIcon(mShowX, mLevel);
notifyChanged();
}
@@ -184,13 +192,13 @@
}
- private void updateIcon(int level) {
+ private void updateIcon(boolean showX, int level) {
if (level == -1) {
setIcon(null);
return;
}
- final Drawable drawable = mIconInjector.getIcon(level);
+ final Drawable drawable = mIconInjector.getIcon(showX, level);
if (drawable != null) {
drawable.setTintList(Utils.getColorAttr(getContext(),
android.R.attr.colorControlNormal));
@@ -260,8 +268,8 @@
mContext = context;
}
- public Drawable getIcon(int level) {
- return mContext.getDrawable(Utils.getWifiIconResource(level));
+ public Drawable getIcon(boolean showX, int level) {
+ return mContext.getDrawable(Utils.getWifiIconResource(showX, level));
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index d7e76a1..44c920c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -13,6 +13,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import android.content.Context;
import android.content.Intent;
@@ -189,10 +190,12 @@
}
}
updateStatusLabel();
+ mCallback.run();
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
// Default to -200 as its below WifiManager.MIN_RSSI.
updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200));
updateStatusLabel();
+ mCallback.run();
}
}
@@ -215,13 +218,15 @@
private void updateStatusLabel() {
NetworkCapabilities networkCapabilities;
- final Network currentWifiNetwork = mWifiManager.getCurrentNetwork();
- if (currentWifiNetwork != null && currentWifiNetwork.equals(mDefaultNetwork)) {
+ isDefaultNetwork = false;
+ if (mDefaultNetworkCapabilities != null) {
+ isDefaultNetwork = mDefaultNetworkCapabilities.hasTransport(
+ NetworkCapabilities.TRANSPORT_WIFI);
+ }
+ if (isDefaultNetwork) {
// Wifi is connected and the default network.
- isDefaultNetwork = true;
networkCapabilities = mDefaultNetworkCapabilities;
} else {
- isDefaultNetwork = false;
networkCapabilities = mConnectivityManager.getNetworkCapabilities(
mWifiManager.getCurrentNetwork());
}
@@ -243,6 +248,10 @@
statusLabel = mContext.getString(R.string.wifi_status_no_internet);
}
return;
+ } else if (!isDefaultNetwork && mDefaultNetworkCapabilities != null
+ && mDefaultNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+ statusLabel = mContext.getString(R.string.wifi_connected_low_quality);
+ return;
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 9b4b97e..1769053 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -17,11 +17,14 @@
package com.android.settingslib.drawer;
import static com.android.settingslib.drawer.TileUtils.IA_SETTINGS_ACTION;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
+import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
+import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
import static com.google.common.truth.Truth.assertThat;
@@ -189,7 +192,7 @@
List<Tile> outTiles = new ArrayList<>();
List<ResolveInfo> info = new ArrayList<>();
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY, "my title", 0);
+ URI_GET_SUMMARY, "my title", 0, PROFILE_ALL);
info.add(resolveInfo);
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
@@ -211,7 +214,7 @@
List<Tile> outTiles = new ArrayList<>();
List<ResolveInfo> info = new ArrayList<>();
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY, null, 123);
+ URI_GET_SUMMARY, null, 123, PROFILE_ALL);
info.add(resolveInfo);
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
@@ -235,7 +238,7 @@
List<Tile> outTiles = new ArrayList<>();
List<ResolveInfo> info = new ArrayList<>();
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY, null, 123);
+ URI_GET_SUMMARY, null, 123, PROFILE_ALL);
resolveInfo.activityInfo.packageName = "com.android.settings";
resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
info.add(resolveInfo);
@@ -258,7 +261,7 @@
final List<Tile> outTiles = new ArrayList<>();
final List<ResolveInfo> info = new ArrayList<>();
final ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY, null, 123);
+ URI_GET_SUMMARY, null, 123, PROFILE_ALL);
resolveInfo.activityInfo.packageName = "com.android.settings";
resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
info.add(resolveInfo);
@@ -290,7 +293,7 @@
List<Tile> outTiles = new ArrayList<>();
List<ResolveInfo> info = new ArrayList<>();
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY, null, 123);
+ URI_GET_SUMMARY, null, 123, PROFILE_ALL);
resolveInfo.activityInfo.metaData
.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
info.add(resolveInfo);
@@ -327,6 +330,26 @@
assertThat(outTiles).hasSize(2);
}
+ @Test
+ public void loadTilesForAction_isPrimaryProfileOnly_shouldSkipNonPrimaryUserTiles() {
+ Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+ List<Tile> outTiles = new ArrayList<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+ URI_GET_SUMMARY, null, 123, PROFILE_PRIMARY);
+ info.add(resolveInfo);
+
+ when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
+ .thenReturn(info);
+ when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+ anyInt())).thenReturn(info);
+
+ TileUtils.loadTilesForAction(mContext, new UserHandle(10), IA_SETTINGS_ACTION,
+ addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
+
+ assertThat(outTiles).isEmpty();
+ }
+
public static ResolveInfo newInfo(boolean systemApp, String category) {
return newInfo(systemApp, category, null);
}
@@ -337,14 +360,14 @@
private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
String iconUri, String summaryUri) {
- return newInfo(systemApp, category, keyHint, iconUri, summaryUri, null, 0);
+ return newInfo(systemApp, category, keyHint, iconUri, summaryUri, null, 0, PROFILE_ALL);
}
private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
- String iconUri, String summaryUri, String title, int titleResId) {
+ String iconUri, String summaryUri, String title, int titleResId, String profile) {
final Bundle metaData = newMetaData(category, keyHint, iconUri, summaryUri, title,
- titleResId);
+ titleResId, profile);
final ResolveInfo info = new ResolveInfo();
info.system = systemApp;
@@ -358,6 +381,7 @@
info.providerInfo.packageName = "abc";
info.providerInfo.name = "456";
info.providerInfo.authority = "auth";
+ info.providerInfo.metaData = metaData;
ShadowTileUtils.setMetaData(metaData);
info.providerInfo.applicationInfo = new ApplicationInfo();
@@ -369,7 +393,7 @@
}
private static Bundle newMetaData(String category, String keyHint, String iconUri,
- String summaryUri, String title, int titleResId) {
+ String summaryUri, String title, int titleResId, String profile) {
final Bundle metaData = new Bundle();
metaData.putString("com.android.settings.category", category);
metaData.putInt(META_DATA_PREFERENCE_ICON, 314159);
@@ -388,6 +412,9 @@
} else if (title != null) {
metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
}
+ if (profile != null) {
+ metaData.putString(META_DATA_KEY_PROFILE, profile);
+ }
return metaData;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java
index 46e699d..40af7dc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -29,6 +30,7 @@
import com.android.settingslib.R;
import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectedInfo;
import org.junit.Before;
import org.junit.Test;
@@ -62,6 +64,17 @@
@Mock
private Drawable mMockDrawable4;
+ @Mock
+ private Drawable mMockShowXDrawable0;
+ @Mock
+ private Drawable mMockShowXDrawable1;
+ @Mock
+ private Drawable mMockShowXDrawable2;
+ @Mock
+ private Drawable mMockShowXDrawable3;
+ @Mock
+ private Drawable mMockShowXDrawable4;
+
private static final String MOCK_TITLE = "title";
private static final String MOCK_SUMMARY = "summary";
private static final String FAKE_URI_STRING = "fakeuri";
@@ -75,11 +88,22 @@
when(mMockWifiEntry.getTitle()).thenReturn(MOCK_TITLE);
when(mMockWifiEntry.getSummary(false /* concise */)).thenReturn(MOCK_SUMMARY);
- when(mMockIconInjector.getIcon(0)).thenReturn(mMockDrawable0);
- when(mMockIconInjector.getIcon(1)).thenReturn(mMockDrawable1);
- when(mMockIconInjector.getIcon(2)).thenReturn(mMockDrawable2);
- when(mMockIconInjector.getIcon(3)).thenReturn(mMockDrawable3);
- when(mMockIconInjector.getIcon(4)).thenReturn(mMockDrawable4);
+ when(mMockIconInjector.getIcon(false /* showX */, 0)).thenReturn(mMockDrawable0);
+ when(mMockIconInjector.getIcon(false /* showX */, 1)).thenReturn(mMockDrawable1);
+ when(mMockIconInjector.getIcon(false /* showX */, 2)).thenReturn(mMockDrawable2);
+ when(mMockIconInjector.getIcon(false /* showX */, 3)).thenReturn(mMockDrawable3);
+ when(mMockIconInjector.getIcon(false /* showX */, 4)).thenReturn(mMockDrawable4);
+
+ when(mMockIconInjector.getIcon(true /* showX */, 0))
+ .thenReturn(mMockShowXDrawable0);
+ when(mMockIconInjector.getIcon(true /* showX */, 1))
+ .thenReturn(mMockShowXDrawable1);
+ when(mMockIconInjector.getIcon(true /* showX */, 2))
+ .thenReturn(mMockShowXDrawable2);
+ when(mMockIconInjector.getIcon(true /* showX */, 3))
+ .thenReturn(mMockShowXDrawable3);
+ when(mMockIconInjector.getIcon(true /* showX */, 4))
+ .thenReturn(mMockShowXDrawable4);
}
@Test
@@ -155,6 +179,70 @@
}
@Test
+ public void levelChanged_notDefaultWifiRefresh_shouldUpdateLevelIcon() {
+ final List<Drawable> iconList = new ArrayList<>();
+ final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class);
+ mockConnectedInfo.isDefaultNetwork = false;
+ when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(2);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(3);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(4);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(-1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+
+ assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1,
+ mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null);
+ }
+
+ @Test
+ public void levelChanged_notValidatedWifiRefresh_shouldUpdateLevelIcon() {
+ final List<Drawable> iconList = new ArrayList<>();
+ final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class);
+ mockConnectedInfo.isValidated = false;
+ when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(2);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(3);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(4);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(-1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+
+ assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1,
+ mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null);
+ }
+
+ @Test
public void notNull_whenGetHelpUriString_shouldSetImageButtonVisible() {
when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING);
final WifiEntryPreference pref =
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index d05e6e1..efaef21 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -165,7 +165,9 @@
Settings.Secure.AWARE_TAP_PAUSE_TOUCH_COUNT,
Settings.Secure.PEOPLE_STRIP,
Settings.Secure.MEDIA_CONTROLS_RESUME,
+ Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index fa810bd..6436355 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -244,6 +244,8 @@
VALIDATORS.put(Secure.TAP_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
+ COLON_SEPARATED_PACKAGE_LIST_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
new InclusiveIntegerRangeValidator(
Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
@@ -251,5 +253,6 @@
VALIDATORS.put(
Secure.ACCESSIBILITY_BUTTON_TARGETS,
ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.ADAPTIVE_CONNECTIVITY_ENABLED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index aae72e5..845c0a3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1979,6 +1979,9 @@
dumpSetting(s, p,
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS);
+ dumpSetting(s, p,
+ Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED,
+ SecureSettingsProto.ADAPTIVE_CONNECTIVITY_ENABLED);
final long controlsToken = p.start(SecureSettingsProto.CONTROLS);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
index 6e5b8890..66aa7ba 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
@@ -35,19 +35,17 @@
public class WriteFallbackSettingsFilesJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters params) {
- switch (params.getJobId()) {
- case WRITE_FALLBACK_SETTINGS_FILES_JOB_ID:
- final List<String> settingsFiles = new ArrayList<>();
- settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SECURE, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SSAID, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, ""));
- SettingsProvider.writeFallBackSettingsFiles(settingsFiles);
- return true;
- default:
- return false;
+ if (params.getJobId() != WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) {
+ return false;
}
+ final List<String> settingsFiles = new ArrayList<>();
+ settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SECURE, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SSAID, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, ""));
+ SettingsProvider.writeFallBackSettingsFiles(settingsFiles);
+ return false;
}
@Override
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b142cfb7..570c2ab3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -317,19 +317,6 @@
<!-- Permissions required for CTS test - AdbManagerTest -->
<uses-permission android:name="android.permission.MANAGE_DEBUGGING" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases, AtsCarDeviceApp -->
- <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo, AtsAudioDeviceTestCases -->
- <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo -->
- <uses-permission android:name="android.car.permission.CAR_DIAGNOSTICS" />
- <!-- Permissions required for ATS tests - AtsDeviceInfo -->
- <uses-permission android:name="android.car.permission.CLEAR_CAR_DIAGNOSTICS" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases -->
- <uses-permission android:name="android.car.permission.CONTROL_APP_BLOCKING" />
- <!-- Permissions required for ATS tests - AtsCarHostTestCases -->
- <uses-permission android:name="android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION" />
-
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/res/values-bn/strings.xml b/packages/Shell/res/values-bn/strings.xml
new file mode 100644
index 0000000..ede125b
--- /dev/null
+++ b/packages/Shell/res/values-bn/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"শেল"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"ত্রুটির প্রতিবেদন"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> তৈরি করা হচ্ছে"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> ক্যাপচার করা হয়েছে"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"ত্রুটির প্রতিবেদনে বিশদ বিবরণ যোগ করা হচ্ছে"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"অনুগ্রহ করে অপেক্ষা করুন..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ফোনে শীঘ্রই ত্রুটির প্রতিবেদন দেখা যাবে"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"আপনার ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"কোনো স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন, বা স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"ত্রুটির প্রতিবেদনগুলিতে থাকা ডেটা, সিস্টেমের বিভিন্ন লগ ফাইলগুলি থেকে আসে, যাতে আপনার বিবেচনা অনুযায়ী সংবেদনশীল ডেটা (যেমন, অ্যাপ্লিকেশানের ব্যবহার এবং লোকেশন ডেটা) থাকতে পারে৷ আপনি বিশ্বাস করেন শুধুমাত্র এমন অ্যাপ্লিকেশান এবং ব্যক্তিদের সাথেই ত্রুটির প্রতিবেদনগুলিকে শেয়ার করুন৷"</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"আর দেখাবেন না"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"ত্রুটির প্রতিবেদনগুলি"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"ত্রুটির প্রতিবেদনের ফাইলটি পড়া যায়নি"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"জিপ ফাইলে ত্রুটি প্রতিবেদনের বিশদ বিবরণ যোগ করা যায়নি"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"নামবিহীন"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"বিশদ বিবরণ"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রিনশট নিন"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"স্ক্রিনশট সফলভাবে নেওয়া হয়েছে৷"</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রিনশট নেওয়া যায়নি৷"</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> এর বিশদ বিবরণ"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"ফাইলের নাম"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"ত্রুটির শীর্ষক"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"ত্রুটির সারাংশ"</string>
+ <string name="save" msgid="4781509040564835759">"সেভ করুন"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"ত্রুটির প্রতিবেদন শেয়ার করুন"</string>
+</resources>
diff --git a/packages/Shell/res/values-eu/strings.xml b/packages/Shell/res/values-eu/strings.xml
new file mode 100644
index 0000000..5d32cab
--- /dev/null
+++ b/packages/Shell/res/values-eu/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Akatsen txostenak"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egiten ari gara"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egin da"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Akatsen txostenean xehetasunak gehitzen"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Itxaron, mesedez…"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Akatsen txostena telefonoan agertuko da laster"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Hautatu hau akatsen txostena partekatzeko"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Sakatu akatsen txostena partekatzeko"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Hautatu hau akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Errore-txostenek sistemaren erregistro-fitxategietako datuak dauzkate, eta, haietan, kontuzkotzat jotzen duzun informazioa ager daiteke (adibidez, aplikazioen erabilera eta kokapen-datuak). Errore-txostenak partekatzen badituzu, partekatu soilik pertsona eta aplikazio fidagarriekin."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ez erakutsi berriro"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Akatsen txostenak"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Ezin izan da irakurri akatsen txostena"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Ezin izan dira gehitu akatsen txostenaren xehetasunak ZIP fitxategian"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"izengabea"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Xehetasunak"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Pantaila-argazkia"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Atera da pantaila-argazkia."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ezin izan da atera pantaila-argazkia."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostenaren xehetasunak"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Fitxategi-izena"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Akatsaren izena"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Akatsaren laburpena"</string>
+ <string name="save" msgid="4781509040564835759">"Gorde"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Partekatu akatsen txostena"</string>
+</resources>
diff --git a/packages/Shell/res/values-gl/strings.xml b/packages/Shell/res/values-gl/strings.xml
new file mode 100644
index 0000000..912dc85
--- /dev/null
+++ b/packages/Shell/res/values-gl/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Informes de erros"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Estase xerando o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Rexistrouse o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Engadindo detalles ao informe de erro"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Agarda..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"O informe de erros aparecerá no teléfono en breve"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Selecciona para compartir o teu informe de erros"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir o teu informe de erros"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Selecciona para compartir o informe de erros sen captura de pantalla ou agarda a que acabe a captura"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Os informes de erros conteñen datos dos distintos ficheiros de rexistro do sistema, os cales poden incluír datos que consideres confidenciais (coma o uso de aplicacións e os datos de localización). Comparte os informes de erros só coas persoas e aplicacións nas que confíes."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Non mostrar outra vez"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de erros"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Non se puido ler o ficheiro de informe de erros"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Non se puideron engadir os detalles do informe de erro ao ficheiro zip"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"sen nome"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Detalles"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"A captura de pantalla realizouse correctamente."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Non se puido realizar a captura de pantalla."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalles do informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Nome do ficheiro"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Título do informe de erros"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Resumo do informe de erros"</string>
+ <string name="save" msgid="4781509040564835759">"Gardar"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Compartir informe de erros"</string>
+</resources>
diff --git a/packages/Shell/res/values-is/strings.xml b/packages/Shell/res/values-is/strings.xml
new file mode 100644
index 0000000..4989e87
--- /dev/null
+++ b/packages/Shell/res/values-is/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Skipanalína"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Villutilkynningar"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Verið er að búa til villutilkynningu <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Villutilkynning <xliff:g id="ID">#%d</xliff:g> búin til"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Bætir upplýsingum við villutilkynningu"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Augnablik..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Villuskýrslan birtist brátt í símanum"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Veldu að deila villutilkynningunni"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ýttu til að deila villutilkynningunni"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Veldu að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Villutilkynningar innihalda gögn úr ýmsum annálaskrám kerfisins sem gætu innihaldið upplýsingar sem þú telur viðkvæmar (til dæmis notkun forrita og staðsetningarupplýsingar). Deildu villutilkynningum bara með fólki og forritum sem þú treystir."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ekki sýna þetta aftur"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Villutilkynningar"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Ekki var hægt að lesa úr villuskýrslunni"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Ekki tókst að bæta upplýsingum um villutilkynningu við ZIP-skrá"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"án heitis"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Nánar"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjámynd"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skjámynd tekin."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekki tókst að taka skjámynd."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Upplýsingar villutilkynningar <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Skráarheiti"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Heiti villu"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Villusamantekt"</string>
+ <string name="save" msgid="4781509040564835759">"Vista"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Deila villutilkynningu"</string>
+</resources>
diff --git a/packages/Shell/res/values-ky/strings.xml b/packages/Shell/res/values-ky/strings.xml
new file mode 100644
index 0000000..3567ac2
--- /dev/null
+++ b/packages/Shell/res/values-ky/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Кабык"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Мүчүлүштүк тууралуу кабар берүүлөр"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> түзүлүүдө"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Мүчүлүштүк жөнүндө кабардын чоо-жайы кошулууда"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күтө туруңуз…"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Мүчүлүштүктөр жөнүндө кабар жакында телефонго чыгат"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Мүчүлүштүк тууралуу кабарды жөнөтүү үчүн таптап коюңуз"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Мүчүлүштүк тууралуу билдирүүңүздү бөлүшүү үчүн таптап коюңуз"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Мүчүлүштүк тууралуу кабарды скриншотсуз жөнөтүү үчүн солго серпиңиз же скриншот даяр болгуча күтүңүз"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Мүчүлүштүктөр тууралуу билдирүүлөрдө тутумдун ар кандай таржымалдарынан алынган дайындар, ошондой эле купуя маалымат камтылышы мүмкүн (мисалы, жайгашкан жер сыяктуу). Мындай билдирүүлөрдү бир гана ишеничтүү адамдар жана колдонмолор менен бөлүшүңүз."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Экинчи көрүнбөсүн"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоо"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Мүчүлүштүк тууралуу кабарлаган файл окулбай койду"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Мүчүлүштүктөр жөнүндө кабардын чоо-жайы zip файлына кошулбай койду"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"аталышы жок"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Чоо-жайы"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Скриншот"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Скриншот ийгиликтүү тартылды."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот тартылбай койду."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Мүчүлүштүк тууралуу билдирүүнүн <xliff:g id="ID">#%d</xliff:g> чоо-жайы"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Файлдын аталышы"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Мүчүлүштүктүн аталышы"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Мүчүлүштүк корутундусу"</string>
+ <string name="save" msgid="4781509040564835759">"Сактоо"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Мүчүлүштүк тууралуу кабарлоо"</string>
+</resources>
diff --git a/packages/Shell/res/values-mk/strings.xml b/packages/Shell/res/values-mk/strings.xml
new file mode 100644
index 0000000..3d18d30
--- /dev/null
+++ b/packages/Shell/res/values-mk/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Извештаи за грешки"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Се генерира извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештајот за грешки <xliff:g id="ID">#%d</xliff:g> е снимен"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Се додаваат детали на извештајот за грешка"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Почекајте..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Извештајот за грешки наскоро ќе се појави на телефонот"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Изберете да го споделите извештајот за грешки"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Допрете за да го споделите извештајот за грешки"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Изберете да го спод. извештајот за грешки без слика од екранот или почекајте да се подготви сликата"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи и податоци што можеби ги сметате за чувствителни (како што се користење на апликациите и податоци за локацијата). Извештаите за грешки споделувајте ги само со апликации и луѓе во кои имате доверба."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Не покажувај повторно"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаи за грешки"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Датотеката со извештај за грешка не можеше да се прочита"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Не можевме да ги додадеме деталите на извештајот за грешки во zip-датотеката"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"неименувани"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Детали"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Слика од екранот"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Успешно е направена слика од екранот."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не може да се направи слика од екранот."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Детали за извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Име на датотека"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Наслов на грешката"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Преглед на грешката"</string>
+ <string name="save" msgid="4781509040564835759">"Зачувај"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Споделете извештај за грешки"</string>
+</resources>
diff --git a/packages/Shell/res/values-ml/strings.xml b/packages/Shell/res/values-ml/strings.xml
new file mode 100644
index 0000000..78b43bb
--- /dev/null
+++ b/packages/Shell/res/values-ml/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"ഷെൽ"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"ബഗ് റിപ്പോർട്ടുകൾ"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> സൃഷ്ടിക്കുന്നു"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"ബഗ് റിപ്പോർട്ടിലേക്ക് വിശദാംശങ്ങൾ ചേർക്കുന്നു"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"കാത്തിരിക്കുക..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ബഗ് റിപ്പോർട്ട് താമസിയാതെ ഫോണിൽ ദൃശ്യമാകും"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നതിന് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ ബഗ് റിപ്പോർട്ട് പങ്കിടുക"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"ബഗ് റിപ്പോർട്ടുകളിൽ സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു, ഇതിൽ നിങ്ങൾ രഹസ്യ സ്വഭാവമുള്ളവയായി പരിഗണിക്കുന്ന വിവരങ്ങളും (ആപ്പ് ഉപയോഗ വിവരങ്ങൾ, ലൊക്കേഷൻ വിവരങ്ങൾ എന്നിവ പോലെ) ഉൾപ്പെടാം. നിങ്ങൾ വിശ്വസിക്കുന്ന ആപ്പുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"വീണ്ടും കാണിക്കരുത്"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"ബഗ് റിപ്പോർട്ടുകൾ"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"ബഗ് റിപ്പോർട്ട് ഫയൽ വായിക്കാനായില്ല"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"സിപ്പ് ഫയലിലേക്ക് ബഗ് റിപ്പോർട്ട് വിശദാംശങ്ങൾ ചേർക്കാൻ കഴിഞ്ഞില്ല"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"പേരില്ലാത്തവർ"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"വിശദാംശങ്ങൾ"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"സ്ക്രീൻഷോട്ട്"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> വിശദാംശങ്ങൾ"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"ഫയല്നാമം"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"ബഗിന്റെ പേര്"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"ബഗ് സംഗ്രഹം"</string>
+ <string name="save" msgid="4781509040564835759">"സംരക്ഷിക്കുക"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"ബഗ് റിപ്പോർട്ട് പങ്കിടുക"</string>
+</resources>
diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml
new file mode 100644
index 0000000..9595e28
--- /dev/null
+++ b/packages/Shell/res/values-mr/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"शेल"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"बग रीपोर्ट"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"दोष अहवालामध्ये तपशील जोडत आहे"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करा..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"फोनवर बग रीपोर्ट लवकरच दिसेल"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"तुमचा बग रीपोर्ट शेअर करण्यासाठी निवडा"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तुमचा बग रीपोर्ट स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"पुन्हा दर्शवू नका"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रीपोर्ट"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाईल वाचणे शक्य झाले नाही"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाईल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामित"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"तपशील"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट यशस्वीरित्या घेतला."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तपशील"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"फाईलनाव"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"दोष शीर्षक"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"दोष सारांश"</string>
+ <string name="save" msgid="4781509040564835759">"सेव्ह करा"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रीपोर्ट शेअर करा"</string>
+</resources>
diff --git a/packages/Shell/res/values-my/strings.xml b/packages/Shell/res/values-my/strings.xml
new file mode 100644
index 0000000..2376ffd
--- /dev/null
+++ b/packages/Shell/res/values-my/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"အခွံ"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"ချွတ်ယွင်းမှု အစီရင်ခံစာများ"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုထုတ်နေပါသည်"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုရယူထားပြီးပါပြီ"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"ချွတ်ယွင်းချက်အစီရင်ခံချက်သို့ အသေးစိတ်များပေါင်းထည့်ရန်"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"ခေတ္တစောင့်ပါ..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို မကြာခင် ဖုန်းထဲတွင် မြင်တွေ့ရပါလိမ့်မည်"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို မျှဝေရန် ရွေးချယ်ပါ"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"သင့်ချွတ်ယွင်းမှုအစီရင်ခံချက်ကို မျှဝေရန် တို့ပါ"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"ချွတ်ယွင်းမှုအစီရင်ခံစာကို ဖန်သားပြင်ပုံ မပါဘဲမျှဝေပါ (သို့) ဖန်သားပြင်ပုံ ရိုက်ပြီးသည်အထိ စောင့်ပါ"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"ချွတ်ယွင်းချက်အစီရင်ခံစာများတွင် သင့်အတွက် အရေးကြီးသည့် ဒေတာများ (အက်ပ်အသုံးပြုမှုနှင့် တည်နေရာအချက်အလက် ကဲ့သို့) ပါဝင်သည့် စနစ်၏မှတ်တမ်းဖိုင်မျိုးစုံပါဝင်ပါသည်။ ချွတ်ယွင်းချက်အစီရင်ခံစာများကို သင်ယုံကြည်စိတ်ချရသည့်လူများ၊ အက်ပ်များနှင့်သာ မျှဝေပါ။"</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"နောက်ထပ်မပြပါနှင့်"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"ချွတ်ယွင်းမှု အစီရင်ခံစာများ"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို ဖတ်၍မရပါ"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"ဇစ်ဖိုင်သို့ ချွတ်ယွင်းချက် အစီရင်ခံစာအသေးစိတ် အချက်အလက်များကို ထည့်၍မရပါ"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"အမည်မဲ့"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"အသေးစိတ်များ"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ဖန်သားပြင်ဓာတ်ပုံ အောင်မြင်စွာရိုက်ပြီးပါပြီ။"</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ မရိုက်နိုင်ပါ"</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> အသေးစိတ်များ"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"ဖိုင်အမည်"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"ချွတ်ယွင်းချက် ခေါင်းစဉ်"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"ချွတ်ယွင်းချက် အကျဉ်းချုပ်"</string>
+ <string name="save" msgid="4781509040564835759">"သိမ်းရန်"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"ချွတ်ယွင်းချက်မှတ်တမ်း မျှဝေပါ"</string>
+</resources>
diff --git a/packages/Shell/res/values-ta/strings.xml b/packages/Shell/res/values-ta/strings.xml
new file mode 100644
index 0000000..a906abe
--- /dev/null
+++ b/packages/Shell/res/values-ta/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"ஷெல்"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"பிழை அறிக்கைகள்"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> உருவாக்கப்படுகிறது"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> எடுக்கப்பட்டது"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"பிழை அறிக்கையில் விவரங்களைச் சேர்க்கிறது"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"காத்திருக்கவும்…"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"பிழை அறிக்கை சிறிது நேரத்தில் மொபைலில் தோன்றும்"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"பிழை அறிக்கையைப் பகிர, தேர்ந்தெடுக்கவும்"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"பிழை அறிக்கையைப் பகிர, தட்டவும்"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"ஸ்கிரீன்ஷாட் இன்றி பிழை அறிக்கையை பகிர தேர்ந்தெடுக்கவும்/ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ஸ்கிரீன்ஷாட் இல்லாமல் பிழை அறிக்கையைப் பகிர, தட்டவும் அல்லது ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ஸ்கிரீன்ஷாட் இல்லாமல் பிழை அறிக்கையைப் பகிர, தட்டவும் அல்லது ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"பிழை அறிக்கைகளில் முறைமையின் பல்வேறு பதிவுக் கோப்புகளின் தரவு (இதில் முக்கியமானவை என நீங்கள் கருதும் பயன்பாடின் உபயோகம், இருப்பிடத் தரவு போன்றவை அடங்கும்) இருக்கும். நீங்கள் நம்பும் நபர்கள் மற்றும் பயன்பாடுகளுடன் மட்டும் பிழை அறிக்கைகளைப் பகிரவும்."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"மீண்டும் காட்டாதே"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"பிழை அறிக்கைகள்"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"பிழை அறிக்கையைப் படிக்க முடியவில்லை"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"பிழை அறிக்கை விவரங்களை ஜிப் கோப்பில் சேர்க்க முடியவில்லை"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"பெயரிடப்படாதது"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"விவரங்கள்"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ஸ்கிரீன்ஷாட்"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ஸ்கிரீன்ஷாட் எடுக்கப்பட்டது."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ஸ்கிரீன் ஷாட்டை எடுக்க முடியவில்லை."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> இன் விவரங்கள்"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"கோப்புப்பெயர்"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"பிழை தலைப்பு"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"பிழை குறித்த சுருக்க விவரம்"</string>
+ <string name="save" msgid="4781509040564835759">"சேமி"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"பிழை அறிக்கையைப் பகிர்"</string>
+</resources>
diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml
index a917955..f8844e9 100644
--- a/packages/SoundPicker/res/values-ar/strings.xml
+++ b/packages/SoundPicker/res/values-ar/strings.xml
@@ -25,5 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"حذف"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"يتعذر إضافة نغمة رنين مخصصة"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"يتعذر حذف نغمة الرنين المخصصة"</string>
- <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
+ <string name="app_label" msgid="3091611356093417332">"الأصوات"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-cs/strings.xml b/packages/SoundPicker/res/values-cs/strings.xml
index e8fc97e..dc67c96 100644
--- a/packages/SoundPicker/res/values-cs/strings.xml
+++ b/packages/SoundPicker/res/values-cs/strings.xml
@@ -16,14 +16,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ringtone_default" msgid="798836092118824500">"Výchozí vyzváněcí tón"</string>
+ <string name="ringtone_default" msgid="798836092118824500">"Výchozí vyzvánění"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Výchozí zvuk oznámení"</string>
<string name="alarm_sound_default" msgid="4787646764557462649">"Výchozí zvuk budíku"</string>
- <string name="add_ringtone_text" msgid="6642389991738337529">"Přidat vyzváněcí tón"</string>
+ <string name="add_ringtone_text" msgid="6642389991738337529">"Přidat vyzvánění"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Přidat budík"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Přidat oznámení"</string>
<string name="delete_ringtone_text" msgid="201443984070732499">"Smazat"</string>
- <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Vlastní vyzváněcí tón se nepodařilo přidat"</string>
- <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Vlastní vyzváněcí tón se nepodařilo smazat"</string>
+ <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Vlastní vyzvánění se nepodařilo přidat"</string>
+ <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Vlastní vyzvánění se nepodařilo smazat"</string>
<string name="app_label" msgid="3091611356093417332">"Zvuky"</string>
</resources>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 667433c..7b8aba4 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -240,6 +240,8 @@
<!-- Listen app op changes -->
<uses-permission android:name="android.permission.WATCH_APPOPS" />
<uses-permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" />
+ <!-- For handling silent audio recordings -->
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
<!-- to read and change hvac values in a car -->
<uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
@@ -267,6 +269,7 @@
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index 8f24e79..7463d3f 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -75,11 +75,6 @@
public MenuItem getLongpressMenuItem(Context context);
/**
- * @return the {@link MenuItem} to display when app ops icons are pressed.
- */
- public MenuItem getAppOpsMenuItem(Context context);
-
- /**
* @return the {@link MenuItem} to display when snooze item is pressed.
*/
public MenuItem getSnoozeMenuItem(Context context);
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 53eb234..401f3e3 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -27,6 +27,7 @@
<item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
<item name="android:textSize">14dp</item>
<item name="android:background">@drawable/kg_emergency_button_background</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:paddingLeft">12dp</item>
<item name="android:paddingRight">12dp</item>
</style>
diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml
index 2e0580f..1451e2c 100644
--- a/packages/SystemUI/res-product/values-in/strings.xml
+++ b/packages/SystemUI/res-product/values-in/strings.xml
@@ -26,10 +26,10 @@
<string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"Tidak ada kartu SIM dalam tablet."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"Tidak ada kartu SIM dalam ponsel."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"Kode PIN tidak cocok"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan direset, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan direset, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan direset, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan direset, sehingga semua datanya akan dihapus."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
<string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
index 46396e3..4b3534b 100644
--- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -32,6 +32,7 @@
android:gravity="center">
<ImageView
android:id="@+id/screenshot_action_chip_icon"
+ android:tint="@*android:color/accent_device_default"
android:layout_width="@dimen/screenshot_action_chip_icon_size"
android:layout_height="@dimen/screenshot_action_chip_icon_size"
android:layout_marginStart="@dimen/screenshot_action_chip_padding_start"
diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml
index 3c641af..ed870f8 100644
--- a/packages/SystemUI/res/layout/media_view.xml
+++ b/packages/SystemUI/res/layout/media_view.xml
@@ -210,8 +210,98 @@
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size" />
- <!-- Buttons to remove this view when no longer needed -->
- <include
- layout="@layout/qs_media_panel_options"
- android:visibility="gone" />
+ <!-- Constraints are set here as they are the same regardless of host -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/qs_media_panel_outer_padding"
+ android:layout_marginStart="@dimen/qs_media_panel_outer_padding"
+ android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
+ android:id="@+id/media_text"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textColor="@color/media_primary_text"
+ android:text="@string/controls_media_title"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/remove_text"
+ app:layout_constraintVertical_chainStyle="spread_inside"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/qs_media_panel_outer_padding"
+ android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
+ android:id="@+id/remove_text"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:singleLine="true"
+ android:textColor="@color/media_primary_text"
+ android:text="@string/controls_media_close_session"
+ app:layout_constraintTop_toBottomOf="@id/media_text"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/settings"/>
+
+ <FrameLayout
+ android:id="@+id/settings"
+ android:background="@drawable/qs_media_light_source"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/qs_media_panel_outer_padding"
+ android:paddingBottom="@dimen/qs_media_panel_outer_padding"
+ android:minWidth="48dp"
+ android:minHeight="48dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/remove_text">
+
+ <TextView
+ android:layout_gravity="bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textColor="@android:color/white"
+ android:text="@string/controls_media_settings_button" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/cancel"
+ android:background="@drawable/qs_media_light_source"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
+ android:paddingBottom="@dimen/qs_media_panel_outer_padding"
+ android:minWidth="48dp"
+ android:minHeight="48dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/dismiss" >
+
+ <TextView
+ android:layout_gravity="bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textColor="@android:color/white"
+ android:text="@string/cancel" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/dismiss"
+ android:background="@drawable/qs_media_light_source"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
+ android:paddingBottom="@dimen/qs_media_panel_outer_padding"
+ android:minWidth="48dp"
+ android:minHeight="48dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <TextView
+ android:layout_gravity="bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textColor="@android:color/white"
+ android:text="@string/controls_media_dismiss_button"
+ />
+ </FrameLayout>
</com.android.systemui.util.animation.TransitionLayout>
diff --git a/packages/SystemUI/res/layout/qs_media_panel_options.xml b/packages/SystemUI/res/layout/qs_media_panel_options.xml
deleted file mode 100644
index e72c0e8..0000000
--- a/packages/SystemUI/res/layout/qs_media_panel_options.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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
- -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/qs_media_controls_options"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:padding="16dp"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:minWidth="48dp"
- android:layout_gravity="start|bottom"
- android:gravity="bottom"
- android:id="@+id/remove"
- android:orientation="horizontal">
- <ImageView
- android:layout_width="18dp"
- android:layout_height="18dp"
- android:id="@+id/remove_icon"
- android:layout_marginEnd="16dp"
- android:tint="@color/media_primary_text"
- android:src="@drawable/ic_clear"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/remove_text"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:singleLine="true"
- android:textColor="@color/media_primary_text"
- android:text="@string/controls_media_close_session" />
- </LinearLayout>
- <TextView
- android:id="@+id/cancel"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:minWidth="48dp"
- android:layout_gravity="end|bottom"
- android:gravity="bottom"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="@android:color/white"
- android:text="@string/cancel" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index a2a0e64..5139765 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Hervat"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselleer"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deel"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Vee uit"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skermopname is gekanselleer"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skermopname is gestoor, tik om te sien"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skermopname is uitgevee"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Kon nie skermopname uitvee nie"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kon nie toestemmings kry nie"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laai tans aanbevelings"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Versteek die huidige sessie."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Versteek"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Maak toe"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a28dd54..dad126c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -73,7 +73,7 @@
<string name="usb_contaminant_message" msgid="7730476585174719805">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ዩኤስቢ አንቃ"</string>
- <string name="learn_more" msgid="4690632085667273811">"የበለጠ መረዳት"</string>
+ <string name="learn_more" msgid="4690632085667273811">"የበለጠ ለመረዳት"</string>
<string name="compat_mode_on" msgid="4963711187149440884">"ማያ እንዲሞላ አጉላ"</string>
<string name="compat_mode_off" msgid="7682459748279487945">"ማያ ለመሙለት ሳብ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ቅጽበታዊ ገጽ እይታ"</string>
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ከቆመበት ቀጥል"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ይቅር"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ሰርዝ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"የማያ ገጽ ቀረጻ ተቀምጧል፣ ለመመልከት መታ ያድርጉ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ፈቃዶችን ማግኘት አልተቻለም"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገጽ ቀረጻን መጀመር ላይ ስህተት"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ምክሮችን በመጫን ላይ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ሚዲያ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"የአሁኑን ክፍለ-ጊዜ ደብቅ።"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ደብቅ"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"አሰናብት"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index de368b3..f906cf2 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"استئناف"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"إلغاء"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"مشاركة"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"تمّ إلغاء تسجيل الشاشة."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"تمّ حفظ تسجيل الشاشة، انقر لعرضه."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"تمّ حذف تسجيل الشاشة."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"تعذّر الحصول على أذونات."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
@@ -1099,7 +1097,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"جارٍ تحميل الاقتراحات"</string>
<string name="controls_media_title" msgid="1746947284862928133">"الوسائط"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"إخفاء الجلسة الحالية"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"إغلاق"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d5fe50b..9185d95 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ৰখোৱাৰ পৰা পুনৰ আৰম্ভ কৰক"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল কৰক"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"শ্বেয়াৰ কৰক"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"মচক"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ’ল"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ’ল, চাবলৈ টিপক"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"স্ক্রীণ ৰেকৰ্ডিং মচা হ’ল"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাব পৰা নগ\'ল"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"স্ক্ৰীণ ঘূৰাওক"</string>
<string name="accessibility_recent" msgid="901641734769533575">"অৱলোকন"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"সন্ধান কৰক"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"কেমেৰা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফ\'ন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"কণ্ঠধ্বনিৰে সহায়"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ <xliff:g id="CHARGING_TIME">%s</xliff:g> বাকী"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"চ্চার্জ কৰি থকা নাই"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"নেটৱৰ্ক \nনিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
- <string name="description_target_search" msgid="3875069993128855865">"অনুসন্ধান কৰক"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে ওপৰলৈ শ্লাইড কৰক।"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে বাওঁফাললৈ শ্লাইড কৰক।"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"বেটাৰি সঞ্চয়কাৰী অন হৈ আছে"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"কাৰ্যদক্ষতা আৰু নেপথ্য ডেটা হ্ৰাস কৰে"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"বেটাৰি সঞ্চয়কাৰী অফ কৰক"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিঙৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"এই সুবিধাটো প্ৰদান কৰা সেৱাটোৱে আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ জৰিয়তে ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে ?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"বৰ্তমানৰ ছেশ্বনটো লুকুৱাওক।"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকুৱাওক"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"অগ্ৰাহ্য কৰক"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিংসমূহ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c6a7f14..933bb04 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Davam edin"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ləğv edin"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaşın"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Silin"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekranın video çəkimi ləğv edildi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekranın video çəkimi yadda saxlanıldı. Baxmaq üçün klikləyin"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekranın video çəkimi silindi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"İcazələr əldə edilmədi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
@@ -405,7 +403,7 @@
<item quantity="one">%d cihaz</item>
</plurals>
<string name="quick_settings_notifications_label" msgid="3379631363952582758">"Bildirişlər"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"İşartı"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fənər"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera istifadə olunur"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Data istifadəsi"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tövsiyələr yüklənir"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Cari sessiyanı gizlədin."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizlədin"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"İmtina edin"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index efb3e58..abb8a3a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimak ekrana je sačuvan, dodirnite da biste pregledali"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimak ekrana je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Preuzimanje dozvola nije uspelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Sakrijte aktuelnu sesiju."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 799a9c2..77c1606 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Узнавіць"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасаваць"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Абагуліць"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Выдаліць"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запіс экрана скасаваны"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запіс экрана захаваны. Націсніце, каб прагледзець"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запіс экрана выдалены"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Памылка выдалення запісу экрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не ўдалося атрымаць дазволы"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загружаюцца рэкамендацыі"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультымедыя"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Схаваць цяперашні сеанс."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Схаваць"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Адхіліць"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1241d06..6ff1bfce 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Възобновяване"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отказ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Изтриване"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Записването на екрана е анулирано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Записът на екрана е запазен. Докоснете, за да го видите"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Записът на екрана е изтрит"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Извличането на разрешенията не бе успешно."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Скриване на текущата сесия."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Отхвърляне"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 4600459..24805e0 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"আবার চালু করুন"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল করুন"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"শেয়ার করুন"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"মুছুন"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রিন রেকর্ডিং বাতিল করা হয়েছে"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে, দেখতে ট্যাপ করুন"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"স্ক্রিন রেকর্ডিং মুছে ফেলা হয়েছে"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাওয়া যায়নি"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"অ্যাক্সেসযোগ্যতা"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"স্ক্রিন ঘোরান"</string>
<string name="accessibility_recent" msgid="901641734769533575">"এক নজরে"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"খুঁজুন"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"সার্চ"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ক্যামেরা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফোন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ভয়েস সহায়তা"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"পূর্ণ হতে <xliff:g id="CHARGING_TIME">%s</xliff:g> সময় লাগবে"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"চার্জ হচ্ছে না"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"নেটওয়ার্ক নিরীক্ষণ\nকরা হতে পারে"</string>
- <string name="description_target_search" msgid="3875069993128855865">"খুঁজুন"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"সার্চ"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য উপরের দিকে স্লাইড করুন৷"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাঁ দিকে স্লাইড করুন৷"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"বর্তমান সেশন লুকান।"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"খারিজ করুন"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b974b92..830929c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimak ekrana je sačuvan. Dodirnite za prikaz."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimak ekrana je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Greška prilikom brisanja snimka ekrana"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dobijanje odobrenja nije uspjelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Sakrijte trenutnu sesiju."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index b261a45..78ab320 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprèn"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel·la"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Suprimeix"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"S\'ha cancel·lat la gravació de la pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"S\'ha desat la gravació de la pantalla; toca per mostrar"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"S\'ha suprimit la gravació de la pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"No s\'han pogut obtenir els permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimèdia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Amaga la sessió actual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 1c23971..9d661ba 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -95,7 +95,7 @@
<string name="screenrecord_description" msgid="1123231719680353736">"Při nahrávání může systém Android zaznamenávat citlivé údaje, které jsou viditelné na obrazovce nebo které jsou přehrávány na zařízení. Týká se to hesel, údajů o platbě, fotek, zpráv a zvuků."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrát zvuk"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk zařízení"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk ze zařízení, například hudba, hovory a vyzváněcí tóny"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk ze zařízení, například hudba, hovory a vyzvánění"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvuk a mikrofon zařízení"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Spustit"</string>
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Obnovit"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušit"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Smazat"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Nahrávání obrazovky bylo zrušeno"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Záznam obrazovky byl uložen, zobrazíte jej klepnutím"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Záznam obrazovky byl smazán"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodařilo se načíst oprávnění"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítání doporučení"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Skrýt aktuální relaci."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavřít"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d439771..30f92c03 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Genoptag"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuller"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Slet"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skærmoptagelsen er annulleret"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skærmoptagelsen er gemt. Tryk for at se den."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skærmoptagelsen er slettet"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Det lykkedes ikke et hente tilladelserne"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Indlæser anbefalinger"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medie"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Skjul den aktuelle session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Luk"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 5c371bf..e4f5ac2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Fortsetzen"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Abbrechen"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Teilen"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Löschen"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Bildschirmaufzeichnung abgebrochen"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Bildschirmaufzeichnung gespeichert, zum Ansehen tippen"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Bildschirmaufzeichnung gelöscht"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Berechtigungen nicht erhalten"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Energiesparmodus ist aktiviert"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduzierung der Leistung und Hintergrunddaten"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Energiesparmodus deaktivieren"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"Die App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"Die App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise angezeigte Passwörter und Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Der Anbieter dieser App erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Aufnahme oder Stream starten?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Aufnehmen oder Streamen mit der App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" starten?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Du kannst die aktuelle Sitzung ausblenden."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ablehnen"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c221016..32b335ec 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Συνέχιση"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ακύρωση"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Κοινοποίηση"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Διαγραφή"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Η εγγραφή οθόνης ακυρώθηκε"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Η εγγραφή οθόνης αποθηκεύτηκε. Πατήστε για προβολή."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Η εγγραφή οθόνης διαγράφηκε"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Η λήψη αδειών απέτυχε"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Μέσα"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Απόκρυψη της τρέχουσας περιόδου λειτουργίας."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Παράβλεψη"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index b7ad910..3a52a72 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index d180a31..11e0fb9 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index b7ad910..3a52a72 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index b7ad910..3a52a72 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 38dd755..1a02d59 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording canceled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c95cb4f..c27bdd0 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reanudar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Borrar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se canceló la grabación de pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Se guardó la grabación de pantalla; presiona para verla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Se borró la grabación de pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error al borrar la grabación de pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Error al obtener permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contenido multimedia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Oculta la sesión actual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Descartar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index eec4a50..3cbf9a1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Seguir"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se ha cancelado la grabación de la pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Se ha guardado la grabación de la pantalla; toca para verla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Se ha eliminado la grabación de la pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"No se ha podido eliminar la grabación de la pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"No se han podido obtener los permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Ahorro de batería activado"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduce el rendimiento y los datos en segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desactivar Ahorro de batería"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tendrá acceso a toda la información que se muestre en pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"El servicio que ofrece esta función tendrá acceso a toda la información que se muestre en pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tendrá acceso a toda la información que se muestre en la pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"El servicio que ofrece esta función tendrá acceso a toda la información que se muestre en la pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"¿Empezar a grabar o enviar contenido?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"¿Quieres iniciar la grabación o el envío de contenido con <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"¿Iniciar grabación o el envío de contenido en <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"No volver a mostrar"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar la sesión."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cerrar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ea9266e..ec91fcd 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Jätka"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Tühista"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaga"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Kustuta"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekraanikuva salvestamine on tühistatud"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekraanikuva salvestis on salvestatud, puudutage vaatamiseks"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekraanikuva salvestis on kustutatud"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Viga ekraanikuva salvestise kustutamisel"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Lubade hankimine ebaõnnestus"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Peidetakse praegune seanss."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Loobu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 338acbe..9598ddd 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Berrekin"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Utzi"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partekatu"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ezabatu"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Utzi zaio pantaila grabatzeari"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gorde da pantailaren grabaketa; sakatu ikusteko"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ezabatu da pantailaren grabaketa"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Ezin izan dira lortu baimenak"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
@@ -554,7 +552,7 @@
<string name="monitoring_description_named_vpn" msgid="5749932930634037027">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta zaude eta hark sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> eta <xliff:g id="VPN_APP_1">%2$s</xliff:g> aplikazioetara konektatuta zaude, eta haiek sareko jarduerak gainbegira ditzakete, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora dago konektatuta laneko profila, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta duzu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta daukazu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"<xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> aplikazioak kudeatzen du gailu hau."</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> erabiltzen du gailua kudeatzeko."</string>
<string name="monitoring_description_do_body" msgid="7700878065625769970">"Gailuko ezarpenak, enpresa-sarbidea, aplikazioak eta datuak gainbegira eta kudea ditzake administratzaileak, baita gailuaren kokapen-informazioa ere."</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ezkutatu uneko saioa."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Baztertu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 02809ae..703d5ec 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ازسرگیری"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"لغو"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"همرسانی"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ضبط صفحهنمایش لغو شد"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ضبط صفحهنمایش ذخیره شد، برای مشاهده ضربه بزنید"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"فایل ضبط صفحهنمایش حذف شد"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"خطا در حذف فایل ضبط صفحهنمایش"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"مجوزها دریافت نشدند"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحهنمایش"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"درحال بار کردن توصیهها"</string>
<string name="controls_media_title" msgid="1746947284862928133">"رسانه"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"جلسه فعلی پنهان شود."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"رد کردن"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 97a1b44..72e1620 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Jatka"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Peruuta"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaa"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Poista"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Näytön tallennus peruutettu"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Näyttötallenne tallennettu, katso napauttamalla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Näyttötallenne poistettu"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Virhe poistettaessa näyttötallennetta"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Käyttöoikeuksien hakeminen epäonnistui."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ladataan suosituksia"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Piilota nykyinen käyttökerta."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ohita"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 7446fe3..91bb30f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Supprimer"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"L\'enregistrement d\'écran a été annulé"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"L\'enregistrement d\'écran est terminé. Touchez ici pour l\'afficher."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"L\'enregistrement d\'écran a été supprimé"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossible d\'obtenir les autorisations"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Économiseur de pile activé"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Réduire les performances et de fond"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Désactiver la fonction Économiseur de pile"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information visible sur votre écran ou qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et l\'audio que vous faites jouer."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information visible sur votre écran ou qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Le service offrant cette fonction aura accès à toute l\'information qui est visible sur votre écran ou sur ce qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Commencer à enregistrer ou à diffuser?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Commandes multimédias"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Masquer la session en cours."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index f4c651e..59b9cfc 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Supprimer"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Enregistrement de l\'écran annulé"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Enregistrement de l\'écran enregistré. Appuyez pour afficher"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Enregistrement de l\'écran supprimé"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Échec d\'obtention des autorisations"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Économiseur de batterie activé"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Limite les performances et les données en arrière-plan."</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Désactiver l\'économiseur de batterie"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil lors d\'un enregistrement ou d\'une diffusion de contenu. Par exemple, vos mots de passe, vos données de paiement, vos photos, vos messages ou encore vos contenus audio lus."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil pendant un enregistrement ou une diffusion de contenu. Il peut s\'agir de mots de passe, données de paiement, photos, messages ou encore contenus audio lus."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Le service qui fournit cette fonction aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil lors d\'un enregistrement ou d\'une diffusion de contenu. Cela comprend, entre autres, vos mots de passe, vos données de paiement, vos photos, vos messages ou encore les contenus audio que vous lisez."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Démarrer l\'enregistrement ou la diffusion ?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Démarrer l\'enregistrement ou la diffusion avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Masquer la session en cours."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index dcb9538..fe50a97 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Cancelouse a gravación de pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gardouse a gravación de pantalla; toca esta notificación para visualizala"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Eliminouse a gravación de pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Produciuse un erro ao obter os permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendacións"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contido multimedia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Oculta a sesión actual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 4164a55..1e58b04 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ફરી શરૂ કરો"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"રદ કરો"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"શેર કરો"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ડિલીટ કરો"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"સ્ક્રીન રેકોર્ડિંગ રદ કર્યું"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું, જોવા માટે ટૅપ કરો"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કર્યું"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"પરવાનગીઓ મેળવવામાં નિષ્ફળ રહ્યાં"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ઍક્સેસિબિલિટી"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"સ્ક્રીન ફેરવો"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ઝલક"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"શોધો"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"શોધ"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"કૅમેરો"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ફોન"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"મીડિયા"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"હાલનું સત્ર છુપાવો."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"છોડી દો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 85635e9..24f2e6d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"फिर से शुरू करें"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करें"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"मिटाएं"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रिकॉर्डिंग रद्द कर दी गई"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रीन रिकॉर्डिंग सेव की गई, देखने के लिए टैप करें"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रीन रिकॉर्डिंग मिटा दी गई"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"मंज़ूरी नहीं मिल सकी"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
@@ -1077,7 +1075,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सुझाव लोड हो रहे हैं"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"इस मीडिया सेशन को छिपाएं."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"खारिज करें"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b421abf..3ebaef9 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Odustani"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje zaslona otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimanje zaslona spremljeno je, dodirnite da biste ga pregledali"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimanje zaslona izbrisano"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Pogreška prilikom brisanja snimanja zaslona"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dohvaćanje dopuštenja nije uspjelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
@@ -505,10 +503,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Štednja baterije je uključena"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Smanjuje količinu rada i pozadinske podatke"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Isključite Štednju baterije"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Usluga koja pruža ovu funkcionalnost imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Započeti snimanje ili emitiranje?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"Započeti snimanje ili emitiranja pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"Započeti snimanje ili emitiranje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Ne prikazuj ponovo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Sakrij trenutačnu sesiju."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0c6166c..f01ac1d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Folytatás"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Mégse"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Megosztás"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Törlés"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"A képernyő rögzítése megszakítva"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Képernyőfelvétel mentve, koppintson a megtekintéshez"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"A képernyőről készült felvétel törölve"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nincs engedély"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Javaslatok betöltése…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Jelenlegi munkamenet elrejtése."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Elrejtés"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Elvetés"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 24fcc19..65f4325 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Վերսկսել"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Չեղարկել"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Կիսվել"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ջնջել"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Էկրանի տեսագրումը չեղարկվեց"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Էկրանի տեսագրությունը պահվեց։ Հպեք՝ դիտելու համար:"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Էկրանի տեսագրությունը ջնջվեց"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Չհաջողվեց ջնջել տեսագրությունը"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Չհաջողվեց ստանալ անհրաժեշտ թույլտվությունները"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
@@ -337,7 +335,7 @@
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string>
<string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"Էկրանն այժմ ավտոմատ կպտտվի:"</string>
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"Էկրանն այժմ կողպված է հորիզոնական դիրքում:"</string>
- <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղահայաց դիրքում:"</string>
+ <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղաձիգ դիրքում:"</string>
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Մեդիա"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Թաքցրեք ընթացիկ աշխատաշրջանը"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Փակել"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 4dadf0f..ea0dd97 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Lanjutkan"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bagikan"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Hapus"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rekaman layar dibatalkan"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Rekaman layar disimpan, ketuk untuk melihat"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Rekaman layar dihapus"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error saat menghapus rekaman layar"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan izin"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
@@ -847,7 +845,7 @@
</string-array>
<string name="menu_ime" msgid="5677467548258017952">"Pengalih keyboard"</string>
<string name="save" msgid="3392754183673848006">"Simpan"</string>
- <string name="reset" msgid="8715144064608810383">"Setel ulang"</string>
+ <string name="reset" msgid="8715144064608810383">"Reset"</string>
<string name="adjust_button_width" msgid="8313444823666482197">"Sesuaikan lebar tombol"</string>
<string name="clipboard" msgid="8517342737534284617">"Papan klip"</string>
<string name="accessibility_key" msgid="3471162841552818281">"Tombol navigasi khusus"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Menyembunyikan sesi saat ini."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Tutup"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index dc3a10dc..f185c19 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Halda áfram"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hætta við"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deila"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eyða"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Hætt við skjáupptöku"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skjáupptaka vistuð, ýttu til að skoða"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skjáupptöku eytt"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Villa við að eyða skjáupptöku"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Ekki tókst að fá heimildir"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Hleður tillögum"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Margmiðlunarefni"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Fela núverandi lotu."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hunsa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index bc13f99..6ee4415 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Riprendi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annulla"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"CANC"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Registrazione dello schermo annullata"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Registrazione dello schermo salvata. Tocca per visualizzarla."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Registrazione dello schermo eliminata"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossibile ottenere le autorizzazioni"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Caricamento dei consigli"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contenuti multimediali"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Nascondi la sessione attuale."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index fd113d6..29411a6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"המשך"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ביטול"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"מחיקה"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"הקלטת המסך בוטלה"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"הקלטת המסך נשמרה, יש להקיש כדי להציג"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"הקלטת המסך נמחקה"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"שגיאה במחיקת הקלטת המסך"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"קבלת ההרשאות נכשלה"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
@@ -508,7 +506,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"תכונת החיסכון בסוללה פועלת"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"מפחית את הביצועים ונתונים ברקע"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"כיבוי תכונת החיסכון בסוללה"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"לאפליקציה <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"לאפליקציית <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> תהיה גישה לכל המידע הגלוי במסך שלך ולכל תוכן שמופעל במכשיר שלך בזמן הקלטה או העברה (casting). המידע הזה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"לשירות שמספק את הפונקציה הזו תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"להתחיל להקליט או להעביר (cast)?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"להתחיל להקליט או להעביר (cast) באמצעות <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -522,7 +520,7 @@
<string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
- <string name="media_projection_action_text" msgid="3634906766918186440">"התחל כעת"</string>
+ <string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="profile_owned_footer" msgid="2756770645766113964">"ייתכן שהפרופיל נתון למעקב"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ייתכן שהרשת נמצאת במעקב"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"בטעינת המלצות"</string>
<string name="controls_media_title" msgid="1746947284862928133">"מדיה"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"הסתרת הסשן הנוכחי."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"סגירה"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a6e6f9a..a5a92b8 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"再開"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"キャンセル"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"共有"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"削除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"画面の録画をキャンセルしました"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"画面の録画を保存しました。タップで表示できます"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"画面の録画を削除しました"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"画面の録画の削除中にエラーが発生しました"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"権限を取得できませんでした"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"バッテリー セーバー ON"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"パフォーマンスとバックグラウンドデータを制限します"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"バッテリー セーバーを OFF"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>は、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"この機能を提供するサービスは、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
- <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"記録やキャストを開始しますか?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で記録やキャストを開始しますか?"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中やキャスト中に画面に表示されたり、デバイスで再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"この機能を提供するサービスは、録画中やキャスト中に画面に表示されたり、デバイスで再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+ <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"録画やキャストを開始しますか?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> で録画やキャストを開始しますか?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"次回から表示しない"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"すべて消去"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string>
<string name="controls_media_title" msgid="1746947284862928133">"メディア"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"現在のセッションを非表示にします。"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"閉じる"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index ff055fc..0fbabcd 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"გაგრძელება"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"გაუქმება"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"გაზიარება"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"წაშლა"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ეკრანის ჩაწერა გაუქმდა"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ეკრანის ჩანაწერი შენახულია, შეეხეთ სანახავად"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ეკრანის ჩანაწერი წაიშალა"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ნებართვების მიღება ვერ მოხერხდა"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"მიმდინარეობს რეკომენდაციების ჩატვირთვა"</string>
<string name="controls_media_title" msgid="1746947284862928133">"მედია"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"დაიმალოს მიმდინარე სესია"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"დამალვა"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"დახურვა"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index b929c2d..0906c71 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Жалғастыру"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Бас тарту"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Жою"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды бейнеге жазудан бас тартылды"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Экран бейне жазбасы сақталды, көру үшін түртіңіз"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Экран бейне жазбасы жойылды"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Рұқсаттар алынбады"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery saver қосулы"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Өнімділікті және фондық деректерді азайтады"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Battery saver функциясын өшіру"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Осы функцияны ұсынатын қызмет экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> жазу не трансляциялау кезінде экранда көрсетілетін немесе дыбысталатын барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және аудиоматериалдар кіреді."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Осы функцияны ұсынатын қызмет жазу не трансляциялау кезінде экранда көрсетілетін немесе құрылғыда дыбысталатын ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және аудиоматериалдар кіреді."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жазу немесе трансляциялау басталсын ба?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> арқылы жазу немесе трансляциялау басталсын ба?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Қайта көрсетпеу"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультимедиа"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ағымдағы сеансты жасыру"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Жабу"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a2429ee..5bf8f48 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"បន្ត"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"បោះបង់"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ចែករំលែក"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"លុប"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"បានបោះបង់ការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"បានរក្សាទុកការថតសកម្មភាពអេក្រង់។ សូមចុចដើម្បីមើល"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"បានលុបការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"មានបញ្ហាក្នុងការលុបការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"មិនអាចទទួលបានការអនុញ្ញាតទេ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហាក្នុងការចាប់ផ្ដើមថតអេក្រង់"</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"កម្មវិធីសន្សំថ្មបានបើក"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"ការបន្ថយការប្រតិបត្តិ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទកម្មវិធីសន្សំថ្ម"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬបញ្ជូន។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែលផ្ដល់មុខងារនេះនឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬបញ្ជូន។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬភ្ជាប់។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែលផ្ដល់មុខងារនេះនឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬភ្ជាប់។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ចាប់ផ្ដើមថត ឬបញ្ជូនមែនទេ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើមថត ឬបញ្ជូនដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើមថត ឬភ្ជាប់ដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"កុំបង្ហាញម្ដងទៀត"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាតទាំងអស់"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"កំពុងផ្ទុកការណែនាំ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"មេឌៀ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"លាក់វគ្គបច្ចុប្បន្ន។"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"លាក់"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ច្រានចោល"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 53e087c..044ecda 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ಮುಂದುವರಿಸಿ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ರದ್ದುಮಾಡಿ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ಅಳಿಸಿ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಉಳಿಸಲಾಗಿದೆ, ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸಲಾಗಿದೆ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ಅನುಮತಿಗಳನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"ಪರದೆಯನ್ನು ತಿರುಗಿಸಿ"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ಸಮಗ್ರ ನೋಟ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"ಹುಡುಕಿ"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ಕ್ಯಾಮರಾ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ಫೋನ್"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"ನೆಟ್ವರ್ಕ್\n ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ"</string>
- <string name="description_target_search" msgid="3875069993128855865">"ಹುಡುಕಿ"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆನ್ ಆಗಿದೆ"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆಫ್ ಮಾಡಿ"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಸಕಲ ಮಾಹಿತಿಗೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತದೆ. ಇದು ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಕೂಡ ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"ಈ ವೈಶಿಷ್ಟ್ಯವು ಒದಗಿಸುವ ಸೇವೆಗಳು, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಬಳಸಿಕೊಂಡು ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಮೂಲಕ ರೆಕಾರ್ಡಿಂಗ್, ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸದಿರು"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ಶಿಫಾರಸುಗಳು ಲೋಡ್ ಆಗುತ್ತಿವೆ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ಮಾಧ್ಯಮ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ಪ್ರಸ್ತುತ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಿ."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ಮರೆಮಾಡಿ"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ವಜಾಗೊಳಿಸಿ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ff61691..30ed951 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"재개"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"취소"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"공유"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"삭제"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"화면 녹화가 취소되었습니다."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"화면 녹화본이 저장되었습니다. 확인하려면 탭하세요."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"화면 녹화가 삭제되었습니다."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"권한을 확보하지 못했습니다."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"절전 모드 사용 중"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"성능 및 백그라운드 데이터를 줄입니다."</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"절전 모드 사용 중지"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>이(가) 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>이 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"녹화 또는 전송을 시작하시겠습니까?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>(으)로 녹화 또는 전송을 시작하시겠습니까?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>으로 녹화 또는 전송을 시작하시겠습니까?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"다시 표시 안함"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
<string name="controls_media_title" msgid="1746947284862928133">"미디어"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"현재 세션을 숨깁니다."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"닫기"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 661a425..8eab2f1 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Улантуу"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Жокко чыгаруу"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлүшүү"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ооба"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды жаздыруу жокко чыгарылды"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Экранды жаздыруу сакталды, көрүү үчүн таптап коюңуз"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Экранды жаздыруу өчүрүлдү"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Уруксаттар алынбай калды"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
@@ -502,10 +500,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Батареяны үнөмдөгүч режими күйүк"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Иштин майнаптуулугун начарлатып, фондук дайын-даректерди чектейт"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүчтү өчүрүү"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"Бул функцияны аткарган <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кызматы экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Бул функцияны аткарган кызматка экраныңыздагы бардык маалымат же түзмөктө ойнотулуп жаткан нерсе, сырсөздөр, төлөмдөрдүн чоо-жайы, сүрөттөр, билдирүүлөр жана аудио файлдар жеткиликтүү болот."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"Жаздырып же тышкы экранга чыгарып жатканда, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу экраныңыздагы бардык маалыматты же түзмөктө ойнолуп жаткан бардык нерселерди (сырсөздөрдү, төлөмдүн чоо-жайын, сүрөттөрдү, билдирүүлөрдү жана угуп жаткан аудиофайлдарды) көрө алат."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Жаздырып же тышкы экранга чыгарып жатканда, бул колдонмо экраныңыздагы бардык маалыматты же түзмөктө ойнолуп жаткан бардык нерселерди (сырсөздөрдү, төлөмдүн чоо-жайын, сүрөттөрдү, билдирүүлөрдү жана угуп жаткан аудиофайлдарды) көрө алат."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> менен жаздырылып же тышкы экранга чыгарылып башталсынбы?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу аркылуу жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Экинчи көрүнбөсүн"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Учурдагы сеансты жашыруу."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Жабуу"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Жөндөөлөр"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 8e7fba0..14cd211 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ສືບຕໍ່"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ຍົກເລີກ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ແບ່ງປັນ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ລຶບ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ຍົກເລີກການບັນທຶກໜ້າຈໍແລ້ວ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ຈັດເກັບການບັນທຶກໜ້າຈໍ, ແຕະເພື່ອເບິ່ງ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ລຶບການບັນທຶກໜ້າຈໍອອກແລ້ວ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ໂຫຼດສິດອະນຸຍາດບໍ່ສຳເລັດ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ກຳລັງໂຫຼດຄຳແນະນຳ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ມີເດຍ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ເຊື່ອງເຊດຊັນປັດຈຸບັນ."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ປິດໄວ້"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 51606e7..f8f1dc0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Tęsti"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atšaukti"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bendrinti"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ištrinti"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrano įrašymas atšauktas"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrano įrašas išsaugotas, palieskite ir peržiūrėkite"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrano įrašas ištrintas"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ištrinant ekrano įrašą įvyko klaida"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepavyko gauti leidimų"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
@@ -508,7 +506,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Akumuliatoriaus tausojimo priemonė įjungta"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Išjungti Akumuliatoriaus tausojimo priemonę"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"„<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Šią funkcija teikianti paslauga galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Pradėti įrašyti ar perduoti turinį?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Pradėti įrašyti ar perduoti turinį naudojant „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“?"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Įkeliamos rekomendacijos"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medija"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Slėpti dabartinį seansą."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Atsisakyti"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index ccbe7bf..ea1bc77 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Atsākt"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atcelt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Dzēst"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrāna ierakstīšana ir atcelta."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrāna ieraksts ir saglabāts. Pieskarieties, lai to skatītu."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrāna ieraksts ir izdzēsts."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Neizdevās iegūt atļaujas."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Notiek ieteikumu ielāde"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multivide"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Paslēpiet pašreizējo sesiju."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Nerādīt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 561cc6d..9ec598a 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Продолжи"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Сподели"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Избриши"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимањето екран е откажано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Снимката од екранот е зачувана, допрете за да ја видите"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Снимката од екранот е избришана"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Грешка при бришењето на снимката од екранот"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не успеаја да се добијат дозволи"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Штедачот на батерија е вклучен"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Ја намалува изведбата и податоците во заднина"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Исклучете го штедачот на батерија"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе има пристап до сите информации што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како, на пример, лозинки, детали на исплатата, фотографии, пораки и аудио што го пуштате."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услугата што ја обезбедува функцијава ќе има пристап до сите информации што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како, на пример, лозинки, детали на исплатата, фотографии, пораки и аудио што го пуштате."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе има пристап до сите податоци што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува податоци како лозинки, детали за плаќање, фотографии, пораки, аудио што го пуштате итн."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услугата што ја обезбедува функцијава ќе има пристап до сите податоци што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како лозинки, детали за плаќање, фотографии, пораки, аудио што го пуштате итн."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Да почне снимање или емитување?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Да почне снимање или емитување со <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Не покажувај повторно"</string>
@@ -667,7 +665,7 @@
<string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
- <string name="got_it" msgid="477119182261892069">"Разбрав"</string>
+ <string name="got_it" msgid="477119182261892069">"Сфатив"</string>
<string name="tuner_toast" msgid="3812684836514766951">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string>
<string name="remove_from_settings" msgid="633775561782209994">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Аудиовизуелни содржини"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Сокриј ја тековнава сесија."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сокриј"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Отфрли"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e3c655a..277169e 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"പുനരാരംഭിക്കുക"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"റദ്ദാക്കുക"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"പങ്കിടുക"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ഇല്ലാതാക്കുക"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"സ്ക്രീൻ റെക്കോർഡിംഗ് റദ്ദാക്കി"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു, കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കി"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"അനുമതികൾ ലഭിച്ചില്ല"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ഉപയോഗസഹായി"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"സ്ക്രീൻ തിരിക്കുക"</string>
<string name="accessibility_recent" msgid="901641734769533575">"അവലോകനം"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"തിരയൽ"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ക്യാമറ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ഫോണ്"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"വോയ്സ് സഹായം"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"ഫുൾ ചാർജാകാൻ, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"നെറ്റ്വർക്ക്\nനിരീക്ഷിക്കപ്പെടാം"</string>
- <string name="description_target_search" msgid="3875069993128855865">"തിരയൽ"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി മുകളിലേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി ഇടത്തേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് തുടർന്നും കേൾക്കാൻ കഴിയും."</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ബാറ്ററി ലാഭിക്കൽ ഓണാണ്"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്ക്കുന്നു"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കുക"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും ഈ ഫംഗ്ഷൻ ലഭ്യമാക്കുന്ന സേവനത്തിന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഓഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ഉപയോഗിച്ച് റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു"</string>
<string name="controls_media_title" msgid="1746947284862928133">"മീഡിയ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"നിലവിലെ സെഷൻ മറയ്ക്കുക."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്ക്കുക"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ഡിസ്മിസ് ചെയ്യുക"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 74af0fd..49421f6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Үргэлжлүүлэх"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Цуцлах"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Устгах"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Дэлгэцийн бичлэгийг цуцалсан"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Дэлгэцийн бичлэгийг хадгалсан. Харахын тулд товшино уу"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Дэлгэцийн бичлэгийг устгасан"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Зөвшөөрөл авч чадсангүй"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Зөвлөмжүүдийг ачаалж байна"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Одоогийн харилцан үйлдлийг нуугаарай."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Нуух"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Хаах"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 85de07a..6bbf77f 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"पुन्हा सुरू करा"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करा"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेअर करा"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"हटवा"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रेकॉर्डिंग रद्द केले"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रीन रेकॉर्डिंग सेव्ह केली, पाहण्यासाठी टॅप करा"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रीन रेकॉर्डिंग हटवले"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"परवानग्या मिळवता आल्या नाहीत"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"अॅक्सेसिबिलिटी"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"स्क्रीन फिरवा"</string>
<string name="accessibility_recent" msgid="901641734769533575">"अवलोकन"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"शोधा"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"कॅमेरा"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"व्हॉइस सहाय्य"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण होईपर्यंत"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"चार्ज होत नाही"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"नेटवर्कचे परीक्षण\nकेले जाऊ शकते"</string>
- <string name="description_target_search" msgid="3875069993128855865">"शोध"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी वर स्लाइड करा."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"अलार्म, रिमाइंडर, इव्हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात."</string>
@@ -504,8 +502,8 @@
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"बॅटरी सेव्हर बंद करा"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अॅक्सेस <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"हे कार्य पुरवठा करणाऱ्या सेवेस तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अॅक्सेस असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
- <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकॉर्ड किंवा कास्ट करणे सुरू करायचे आहे का ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ने रेकॉर्ड करणे किंवा कास्ट करणे सुरू करा?"</string>
+ <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकॉर्ड करणे किंवा कास्ट करणे सुरू करायचे का ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ने रेकॉर्ड करणे किंवा कास्ट करणे सुरू करायचे का?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"पुन्हा दर्शवू नका"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"शिफारशी लोड करत आहे"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"सध्याचे सेशन लपवा."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लपवा"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"डिसमिस करा"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index dcaded5..b164276 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Sambung semula"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kongsi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Padam"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rakaman skrin dibatalkan"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Rakaman skrin disimpan, ketik untuk melihat"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Rakaman skrin dipadamkan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ralat semasa memadamkan rakaman skrin"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan kebenaran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
@@ -405,7 +403,7 @@
<item quantity="one">%d peranti</item>
</plurals>
<string name="quick_settings_notifications_label" msgid="3379631363952582758">"Pemberitahuan"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu suluh"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu Suluh"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera sedang digunakan"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Data mudah alih"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Penggunaan data"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuatkan cadangan"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Sembunyikan sesi semasa."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Tolak"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index c07c45a..6d71f1d 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ဆက်လုပ်ရန်"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"မလုပ်တော့"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"မျှဝေရန်"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ဖျက်ရန်"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ဖန်သားပြင် ရိုက်ကူးမှု ပယ်ဖျက်လိုက်ပါပြီ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ဖန်သားပြင် ရိုက်ကူးမှု သိမ်းထားသည်၊ ကြည့်ရန် တို့ပါ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ပြီးပါပြီ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ခွင့်ပြုချက် မရယူနိုင်ပါ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ဘက်ထရီ အားထိန်းကို ဖွင့်ထားခြင်း"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"လုပ်ကိုင်မှုကို လျှော့ချလျက် နောက်ခံ ဒေတာကို ကန့်သတ်သည်"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ဘက်ထရီ အားထိန်းကို ပိတ်ရန်"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ဤလုပ်ရပ်အတွက် ဝန်ဆောင်မှုသည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်ဖန်သားပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်နိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ဤလုပ်ရပ်အတွက် ဝန်ဆောင်မှုသည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်ဖန်သားပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပြီး သင့်စက်မှ ဖွင့်နိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> နှင့် ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"နောက်ထပ် မပြပါနှင့်"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string>
<string name="controls_media_title" msgid="1746947284862928133">"မီဒီယာ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"လက်ရှိ စက်ရှင်ကို ဖျောက်ထားမည်။"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ပယ်ရန်"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index bfd5dab..14de00a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Gjenoppta"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Slett"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skjermopptak er avbrutt"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skjermopptaket er lagret. Trykk for å se det"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skjermopptaket er slettet"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Feil ved sletting av skjermopptaket"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kunne ikke få tillatelser"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laster inn anbefalinger"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medier"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Skjul den nåværende økten."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Lukk"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index a39dfb2..f003d27 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"जारी राख्नुहोस्"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द गर्नुहोस्"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"मेट्नुहोस्"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रिनको रेकर्डिङ मेटाइयो"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"अनुमति प्राप्त गर्न सकिएन"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ब्याट्री सेभर अन छ"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"प्रदर्शन र पृष्ठभूमि डेटा घटाउँनुहोस्"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ब्याट्री सेभर अफ गर्नुहोस्"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> मार्फत रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"फेरि नदेखाउनुहोस्"</string>
@@ -716,7 +714,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"फ्लोटिङ सर्टकटमार्फत यो सामग्रीतर्फ तपाईंको ध्यान आकर्षित गर्दछ।"</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल तस्बिर देखाइन्छ"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल फोटो देखाइन्छ"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिङ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
@@ -729,11 +727,11 @@
<string name="see_more_title" msgid="7409317011708185729">"थप हेर्नुहोस्"</string>
<string name="appops_camera" msgid="5215967620896725715">"यो अनुप्रयोगले क्यामेराको प्रयोग गर्दै छ।"</string>
<string name="appops_microphone" msgid="8805468338613070149">"यो अनुप्रयोगले माइक्रोफोनको प्रयोग गर्दै छ।"</string>
- <string name="appops_overlay" msgid="4822261562576558490">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्दै छ।"</string>
+ <string name="appops_overlay" msgid="4822261562576558490">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्दै छ।"</string>
<string name="appops_camera_mic" msgid="7032239823944420431">"यो अनुप्रयोगले माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
- <string name="appops_camera_overlay" msgid="6466845606058816484">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै क्यामेराको प्रयोग गर्दै छ।"</string>
- <string name="appops_mic_overlay" msgid="4609326508944233061">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै माइक्रोफोनको प्रयोग गर्दै छ।"</string>
- <string name="appops_camera_mic_overlay" msgid="5584311236445644095">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
+ <string name="appops_camera_overlay" msgid="6466845606058816484">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै क्यामेराको प्रयोग गर्दै छ।"</string>
+ <string name="appops_mic_overlay" msgid="4609326508944233061">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै माइक्रोफोनको प्रयोग गर्दै छ।"</string>
+ <string name="appops_camera_mic_overlay" msgid="5584311236445644095">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
<string name="notification_appops_settings" msgid="5208974858340445174">"सेटिङहरू"</string>
<string name="notification_appops_ok" msgid="2177609375872784124">"ठिक छ"</string>
<string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> का सूचना सम्बन्धी नियन्त्रणहरूलाई खोलियो"</string>
@@ -1026,7 +1024,7 @@
<string name="priority_onboarding_title" msgid="2893070698479227616">"वार्तालापको प्राथमिकता निर्धारण गरी \"महत्त्वपूर्ण\" बनाइयो"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"महत्वपूर्ण वार्तालापहरू:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखिने छन्"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाउने छन्"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल फोटो देखाउने छन्"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"बुझेँ"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मिडिया"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"हालको सत्र लुकाउनुहोस्।"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लुकाउनुहोस्"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"हटाउनुहोस्"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3145568..679be33 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Hervatten"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuleren"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Delen"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Verwijderen"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Schermopname geannuleerd"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Schermopname opgeslagen, tik om te bekijken"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Schermopname verwijderd"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Fout bij verwijderen van schermopname"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kan rechten niet ophalen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
@@ -354,7 +352,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Gehoorapparaten"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hoortoestellen"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inschakelen..."</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Helderheid"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Aanbevelingen laden"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"De huidige sessie verbergen."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Verbergen"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Sluiten"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index b9db632..8cacc97 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ବାତିଲ୍ କରନ୍ତୁ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ବାତିଲ୍ କରିଦିଆଯାଇଛି"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ ହୋଇଛି, ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିଦିଆଯାଇଛି"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ଅନୁମତି ପାଇବାରେ ଅସଫଳ ହେଲା।"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"ସ୍କ୍ରୀନ୍କୁ ଘୁରାନ୍ତୁ"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ଓଭରଭିଉ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"କ୍ୟାମେରା"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ଫୋନ୍"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ଭଏସ୍ ସହାୟକ"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାକୁ ଆଉ <xliff:g id="CHARGING_TIME">%s</xliff:g> ଅଛି"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"ନେଟ୍ୱର୍କ\nମନିଟର୍ କରାଯାଇପାରେ"</string>
- <string name="description_target_search" msgid="3875069993128855865">"ସର୍ଚ୍ଚ"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ଉପରକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ।"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ବାମକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍, ଭିଡିଓ ଏବଂ ଗେମ୍ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ମିଡିଆ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ବର୍ତ୍ତମାନର ସେସନ୍ ଲୁଚାନ୍ତୁ।"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 7a2effc..a3bc4e0 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ਰੱਦ ਕਰੋ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ਸਾਂਝਾ ਕਰੋ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ਮਿਟਾਓ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ਸਕ੍ਰੀਨ ਦੀ ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕੀਤੀ ਗਈ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ, ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ਇਜਾਜ਼ਤਾਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਨੂੰ ਲੁਕਾਓ।"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ਖਾਰਜ ਕਰੋ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index ae5f3d2..443c8f15 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Wznów"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anuluj"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Usuń"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano nagrywanie zawartości ekranu"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Usunięto nagranie zawartości ekranu"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nie udało się uzyskać uprawnień"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ukryj bieżącą sesję."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odrzuć"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index b19d654..6918ad8 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Excluir"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de tela salva, toque para ver"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de tela excluída"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Economia de bateria ativada"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduz o desempenho e os dados em segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desativar a Economia de bateria"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e áudio que você toca."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão. Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e o áudio que você tocar."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"O serviço que oferece essa função terá acesso a todas as informações visíveis na tela ou reproduzidas durante uma gravação ou transmissão. Isso inclui senhas, detalhes de pagamento, fotos, mensagens e áudio."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Iniciar gravação ou transmissão?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Iniciar gravação ou transmissão com o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar a sessão atual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 982dbcf..9071992 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de ecrã cancelada."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de ecrã guardada. Toque para ver."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de ecrã eliminada."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao eliminar a gravação de ecrã."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Falha ao obter as autorizações."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Oculte a sessão atual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b19d654..6918ad8 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Excluir"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de tela salva, toque para ver"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de tela excluída"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Economia de bateria ativada"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduz o desempenho e os dados em segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desativar a Economia de bateria"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e áudio que você toca."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão. Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e o áudio que você tocar."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"O serviço que oferece essa função terá acesso a todas as informações visíveis na tela ou reproduzidas durante uma gravação ou transmissão. Isso inclui senhas, detalhes de pagamento, fotos, mensagens e áudio."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Iniciar gravação ou transmissão?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Iniciar gravação ou transmissão com o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar a sessão atual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 1b9f34b..12a622c8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reluați"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulați"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Trimiteți"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ștergeți"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Înregistrarea ecranului a fost anulată"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Înregistrarea ecranului a fost salvată. Atingeți pentru vizualizare"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Înregistrarea ecranului a fost ștearsă."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Eroare la ștergerea înregistrării ecranului"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nu s-au obținut permisiunile"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Se încarcă recomandările"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ascunde sesiunea actuală."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ascunde"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Închideți"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 6bf24f5..117e2b2 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Возобновить"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отмена"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Удалить"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запись видео с экрана отменена"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запись видео с экрана сохранена. Чтобы открыть ее, нажмите на уведомление."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запись видео с экрана удалена"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Не удалось удалить запись видео с экрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не удалось получить необходимые разрешения"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Скрыть текущий сеанс?"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Скрыть"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 347ad69..2be74df 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"නැවත අරඹන්න"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"අවලංගු කරන්න"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"බෙදා ගන්න"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"මකන්න"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"තිර පටිගත කිරීම අවලංගු කරන ලදී"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"තිර පටිගත කිරීම සුරකින ලදී, බැලීමට තට්ටු කරන්න"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"තිර පටිගත කිරීම මකන ලදී"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"අවසර ලබා ගැනීමට අසමත් විය"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"නිර්දේශ පූරණය කරමින්"</string>
<string name="controls_media_title" msgid="1746947284862928133">"මාධ්ය"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"වත්මන් සැසිය සඟවන්න."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ඉවත ලන්න"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 986fec6..001b474 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Obnoviť"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušiť"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Odstrániť"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Záznam obrazovky bol zrušený"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Záznam obrazovky bol uložený, zobrazíte ho klepnutím"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Záznam obrazovky bol odstránený"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodarilo sa získať povolenia"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Médiá"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Skryť aktuálnu reláciu."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavrieť"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c44535f..937bb79 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nadaljuj"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Prekliči"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snemanje zaslona je preklicano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Videoposnetek zaslona je shranjen, dotaknite se za ogled"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Videoposnetek zaslona je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Napaka pri brisanju videoposnetka zaslona"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dovoljenj ni bilo mogoče pridobiti"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Predstavnost"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Skrije trenutno sejo."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Opusti"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 6126bd5..97fb032 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -108,15 +108,13 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Vazhdo"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulo"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ndaj"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Fshi"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Regjistrimi i ekranit u anulua"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Regjistrimi i ekranit u ruajt, trokit për ta parë"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Regjistrimi i ekranit u fshi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Marrja e lejeve dështoi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
<string name="usb_preference_title" msgid="1439924437558480718">"Opsionet e transferimit të dosjeve të USB-së"</string>
- <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një lexues \"media\" (MTP)"</string>
+ <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një luajtës të medias (MTP)"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"Montoje si kamerë (PTP)"</string>
<string name="installer_cd_button_title" msgid="5499998592841984743">"Instalo \"Transferimi i skedarëve të Android\" për Mac"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"\"Kursyesi i baterisë\" është i aktivizuar"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Çaktivizo \"Kursyesin e baterisë\""</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione si p.sh. fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Shërbimi që e ofron këtë funksion do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione si p.sh. fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione, si p.sh.: fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Shërbimi që e ofron këtë funksion do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione, si p.sh.: fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Do të fillosh regjistrimin ose transmetimin?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Fillo regjistrimin ose transmetimin me <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Mos e shfaq sërish"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Po ngarkon rekomandimet"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Fshih sesionin aktual."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hiq"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5fccdd0..083e45e 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Настави"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Избриши"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимање екрана је отказано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Снимак екрана је сачуван, додирните да бисте прегледали"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Снимак екрана је избрисан"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Преузимање дозвола није успело"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
@@ -1081,7 +1079,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Сакријте актуелну сесију."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Одбаци"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 5674c04..e2e6b7d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Återuppta"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dela"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Radera"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skärminspelningen har avbrutits"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skärminspelningen har sparats, tryck här om du vill titta på den"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skärminspelningen har raderats"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Det gick inte att radera skärminspelningen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Behörighet saknas"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Dölj den aktuella sessionen."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Stäng"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 72ef2c4..0abb58f 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Endelea"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ghairi"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Futa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Imeghairi mchakato wa kurekodi skrini"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Imehifadhi rekodi ya skrini, gusa ili uangalie"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Imefuta rekodi ya skrini"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Imeshindwa kupata ruhusa"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ficha kipindi cha sasa."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ondoa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 12d4bc0..f98e103 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"மீண்டும் தொடங்கு"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ரத்துசெய்"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"பகிர்"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"நீக்கு"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"திரை ரெக்கார்டிங் ரத்துசெய்யப்பட்டது"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"திரை ரெக்கார்டிங் சேமிக்கப்பட்டது, பார்க்கத் தட்டவும்"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"திரை ரெக்கார்டிங் நீக்கப்பட்டது"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"அனுமதிகளைப் பெற இயலவில்லை"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"பரிந்துரைகளை ஏற்றுகிறது"</string>
<string name="controls_media_title" msgid="1746947284862928133">"மீடியா"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"இந்த அமர்வை மறையுங்கள்."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"மறை"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"மூடுக"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 830a3ae..c9d211c 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"కొనసాగించు"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"రద్దు చేయి"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"షేర్ చేయి"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"తొలగించు"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"స్క్రీన్ రికార్డ్ రద్దు చేయబడింది"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది, చూడటం కోసం నొక్కండి"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"స్క్రీన్ రికార్డింగ్ తొలగించబడింది"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"స్క్రీన్ రికార్డింగ్ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"అనుమతులను పొందడం విఫలమైంది"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
@@ -125,7 +123,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"యాక్సెస్ సామర్థ్యం"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"స్క్రీన్ను తిప్పండి"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ఓవర్వ్యూ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"వెతుకు"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"సెర్చ్"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"కెమెరా"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ఫోన్"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"వాయిస్ అసిస్టెంట్"</string>
@@ -441,7 +439,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"పూర్తిగా నిండటానికి <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ఛార్జ్ కావడం లేదు"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"నెట్వర్క్\nపర్యవేక్షించబడవచ్చు"</string>
- <string name="description_target_search" msgid="3875069993128855865">"శోధించండి"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"సెర్చ్"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం పైకి స్లైడ్ చేయండి."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం ఎడమవైపుకు స్లైడ్ చేయండి."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"మీరు పేర్కొనే అలారాలు, రిమైండర్లు, ఈవెంట్లు మరియు కాలర్ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
<string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ప్రస్తుత సెషన్ను దాచు."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచు"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"విస్మరించు"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్లు"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 178accd..7705be9 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ทำต่อ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ยกเลิก"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"แชร์"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ลบ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ยกเลิกการบันทึกหน้าจอแล้ว"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"บันทึกการบันทึกหน้าจอแล้ว แตะเพื่อดู"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ลบการบันทึกหน้าจอแล้ว"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ขอสิทธิ์ไม่สำเร็จ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"กำลังโหลดคำแนะนำ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"สื่อ"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"ซ่อนเซสชันปัจจุบัน"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ซ่อน"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ปิด"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 7d1f45f..c37c111 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Ituloy"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselahin"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ibahagi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"I-delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Kinansela ang pag-record ng screen"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Na-save ang pag-record ng screen, i-tap para tingnan"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Na-delete ang pag-record ng screen"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error sa pag-delete sa pag-record ng screen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Hindi nakuha ang mga pahintulot"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nilo-load ang rekomendasyon"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Itago ang kasalukuyang session."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Itago"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"I-dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d26c8d8..108f00c 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Devam ettir"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"İptal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Sil"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekran kaydı iptal edildi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekran kaydı tamamlandı, görüntülemek için dokunun"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekran kaydı silindi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"İzinler alınamadı"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Öneriler yükleniyor"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medya"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Mevcut oturumu gizle."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Kapat"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 77347d4..90a512f3 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Відновити"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасувати"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Видалити"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запис екрана скасовано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запис екрана збережено. Натисніть, щоб переглянути"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запис екрана видалено"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не вдалось отримати дозволи"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
@@ -1087,7 +1085,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медіа"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Приховати поточний сеанс."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Закрити"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 7b9ac71..8a69b1c 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"دوبارہ شروع کریں"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"منسوخ کریں"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"اشتراک کریں"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف کریں"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"اسکرین ریکارڈنگ منسوخ ہو گئی"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"اسکرین ریکارڈنگ محفوظ ہو گئی، دیکھنے کیلئے تھپتھپائیں"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"اسکرین ریکارڈنگ حذف ہو گئی"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"اجازتیں حاصل کرنے میں ناکامی"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
<string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"موجودہ سیشن چھپائیں۔"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"برخاست کریں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index ba43141..47dd75c 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Davom etish"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Bekor qilish"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ulashish"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"O‘chirish"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrandan yozib olish bekor qilindi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrandan yozib olingan video saqlandi. Uni ochish uchun bildirishnomani bosing."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrandan yozib olingan video o‘chirib tashlandi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Zarur ruxsatlar olinmadi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
@@ -227,7 +225,7 @@
<string name="data_connection_roaming" msgid="375650836665414797">"Rouming"</string>
<string name="data_connection_edge" msgid="6316755666481405762">"EDGE"</string>
<string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
- <string name="accessibility_no_sim" msgid="1140839832913084973">"SIM karta solinmagan."</string>
+ <string name="accessibility_no_sim" msgid="1140839832913084973">"SIM kartasiz."</string>
<string name="accessibility_cell_data" msgid="172950885786007392">"Mobil internet"</string>
<string name="accessibility_cell_data_on" msgid="691666434519443162">"Mobil internet yoniq"</string>
<string name="cell_data_off_content_description" msgid="9165555931499878044">"Mobil internet yoqilmagan"</string>
@@ -362,7 +360,7 @@
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> rejimi"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Aylanmaydigan qilingan"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Tik holat"</string>
- <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Eniga"</string>
+ <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Yotiq"</string>
<string name="quick_settings_ime_label" msgid="3351174938144332051">"Kiritish usuli"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"Joylashuvni aniqlash xizmati yoqilmagan"</string>
@@ -505,7 +503,7 @@
<string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Bu funksiyani taʼminlovchi xizmat ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Yozib olish yoki translatsiya boshlansinmi?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bilan yozib olinsin yoki translatsiya qilinsinmi?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> orqali yozib olish yoki translatsiya boshlansinmi?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Boshqa ko‘rsatilmasin"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Joriy seans berkitilsin."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Yopish"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 963eb89b9..344e292 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Tiếp tục"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hủy"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Chia sẻ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Xóa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Đã hủy bản ghi màn hình"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Đã lưu bản ghi màn hình, nhấn để xem"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Đã xóa bản ghi màn hình"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Lỗi khi xóa bản ghi màn hình"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Không được cấp đủ quyền"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
@@ -502,8 +500,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Trình tiết kiệm pin đang bật"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Giảm hiệu suất và dữ liệu nền"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Tắt trình tiết kiệm pin"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát trên thiết bị của bạn trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát trên thiết bị của bạn trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Bắt đầu ghi âm/ghi hình hoặc truyền?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Bắt đầu ghi âm/ghi hình hoặc truyền bằng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Không hiển thị lại"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Nội dung nghe nhìn"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Ẩn phiên hiện tại."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Đóng"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9f69429..2a720d8 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"继续"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"删除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消录制屏幕"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"屏幕录制内容已保存,点按即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已删除屏幕录制内容"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"删除屏幕录制内容时出错"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"无法获取权限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在加载推荐内容"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒体"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"隐藏当前会话。"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"关闭"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b4431c4..88e3fb7 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"繼續"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"刪除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄影畫面"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"已儲存錄影畫面,輕按即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已刪除錄影畫面"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除錄影畫面時發生錯誤"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"無法獲得權限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"隱藏目前的工作階段。"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 7405118..ad5e370 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"繼續"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"刪除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄製螢幕畫面"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"已儲存螢幕畫面錄製內容,輕觸即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已刪除螢幕畫面錄製內容"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除螢幕畫面錄製內容時發生錯誤"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"無法取得權限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
@@ -502,7 +500,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"省電模式已開啟"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"降低效能並限制背景數據傳輸"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"關閉省電模式"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"在錄製或投放內容時,提供這項功能的服務可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"要開始錄製或投放內容嗎?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"要使用「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」開始錄製或投放內容嗎?"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"隱藏目前的工作階段。"</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index cb6df33..7303e14 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Qalisa kabusha"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Khansela"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Yabelana"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Susa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ukurekhoda isikrini kukhanseliwe"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ukurekhoda isikrini kulondoloziwe, thepha ukuze ubuke"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ukurekhoda isikrini kususiwe"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Iphutha lokususa ukurekhoda isikrini"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Yehlulekile ukuthola izimvume"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
@@ -1075,7 +1073,7 @@
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ilayisha izincomo"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Imidiya"</string>
<string name="controls_media_close_session" msgid="3957093425905475065">"Fihla iseshini yamanje."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fihla"</string>
+ <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cashisa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5984d8d..0d40a9f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1371,7 +1371,7 @@
<dimen name="controls_app_divider_height">2dp</dimen>
<dimen name="controls_app_divider_side_margin">32dp</dimen>
- <dimen name="controls_card_margin">2dp</dimen>
+ <dimen name="controls_card_margin">@dimen/control_base_item_margin</dimen>
<item name="control_card_elevation" type="dimen" format="float">15</item>
<dimen name="controls_dialog_padding">32dp</dimen>
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 67293c5..f05be06 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -21,5 +21,5 @@
<string name="system_ui_date_pattern" translatable="false">@*android:string/system_ui_date_pattern</string>
<!-- Date format for the always on display. -->
- <item type="string" name="system_ui_aod_date_pattern" translatable="false">eeeMMMd</item>
+ <item type="string" name="system_ui_aod_date_pattern" translatable="false">EEEMMMd</item>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 28c1b02..38501eb 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -278,14 +278,10 @@
<string name="screenrecord_cancel_label">Cancel</string>
<!-- Label for notification action to share screen recording [CHAR LIMIT=35] -->
<string name="screenrecord_share_label">Share</string>
- <!-- Label for notification action to delete a screen recording file [CHAR LIMIT=35] -->
- <string name="screenrecord_delete_label">Delete</string>
<!-- A toast message shown after successfully canceling a screen recording [CHAR LIMIT=NONE] -->
<string name="screenrecord_cancel_success">Screen recording canceled</string>
<!-- Notification text shown after saving a screen recording to prompt the user to view it [CHAR LIMIT=100] -->
<string name="screenrecord_save_message">Screen recording saved, tap to view</string>
- <!-- A toast message shown after successfully deleting a screen recording [CHAR LIMIT=NONE] -->
- <string name="screenrecord_delete_description">Screen recording deleted</string>
<!-- A toast message shown when there is an error deleting a screen recording [CHAR LIMIT=NONE] -->
<string name="screenrecord_delete_error">Error deleting screen recording</string>
<!-- A toast message shown when the screen recording cannot be started due to insufficient permissions [CHAR LIMIT=NONE] -->
@@ -2822,7 +2818,7 @@
<!-- Explanation for closing controls associated with a specific media session [CHAR_LIMIT=NONE] -->
<string name="controls_media_close_session">Hide the current session.</string>
<!-- Label for a button that will hide media controls [CHAR_LIMIT=30] -->
- <string name="controls_media_dismiss_button">Hide</string>
+ <string name="controls_media_dismiss_button">Dismiss</string>
<!-- Label for button to resume media playback [CHAR_LIMIT=NONE] -->
<string name="controls_media_resume">Resume</string>
<!-- Label for button to go to media control settings screen [CHAR_LIMIT=30] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
index 4d968f1..73dc60d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
@@ -26,6 +26,17 @@
private static final String TAG = "WallpaperEngineCompat";
+ /**
+ * Returns true if {@link IWallpaperEngine#scalePreview(Rect)} is available.
+ */
+ public static boolean supportsScalePreview() {
+ try {
+ return IWallpaperEngine.class.getMethod("scalePreview", Rect.class) != null;
+ } catch (NoSuchMethodException | SecurityException e) {
+ return false;
+ }
+ }
+
private final IWallpaperEngine mWrappedEngine;
public WallpaperEngineCompat(IWallpaperEngine wrappedEngine) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 10dcbd6..a84664c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -448,8 +448,8 @@
if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
+ " UpdateSim.onSimCheckResponse: "
+ " attemptsRemaining=" + result.getAttemptsRemaining());
- mStateMachine.reset();
}
+ mStateMachine.reset();
mCheckSimPukThread = null;
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 2deeb12..5f88156 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -39,21 +39,15 @@
*/
@Singleton
public class ForegroundServiceController {
- public static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
- AppOpsManager.OP_RECORD_AUDIO,
- AppOpsManager.OP_COARSE_LOCATION,
- AppOpsManager.OP_FINE_LOCATION};
+ public static final int[] APP_OPS = new int[] {AppOpsManager.OP_SYSTEM_ALERT_WINDOW};
private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
private final Object mMutex = new Object();
- private final NotificationEntryManager mEntryManager;
private final Handler mMainHandler;
@Inject
- public ForegroundServiceController(NotificationEntryManager entryManager,
- AppOpsController appOpsController, @Main Handler mainHandler) {
- mEntryManager = entryManager;
+ public ForegroundServiceController(AppOpsController appOpsController,
+ @Main Handler mainHandler) {
mMainHandler = mainHandler;
appOpsController.addCallback(APP_OPS, (code, uid, packageName, active) -> {
mMainHandler.post(() -> {
@@ -87,19 +81,6 @@
}
/**
- * Returns the keys for notifications from this package using the standard template,
- * if they exist.
- */
- @Nullable
- public ArraySet<String> getStandardLayoutKeys(int userId, String pkg) {
- synchronized (mMutex) {
- final ForegroundServicesUserState services = mUserServices.get(userId);
- if (services == null) return null;
- return services.getStandardLayoutKeys(pkg);
- }
- }
-
- /**
* Gets active app ops for this user and package
*/
@Nullable
@@ -140,31 +121,6 @@
userServices.removeOp(packageName, appOpCode);
}
}
-
- // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // AppOpsCoordinator
- // Update appOps if there are associated pending or visible notifications
- final Set<String> notificationKeys = getStandardLayoutKeys(userId, packageName);
- if (notificationKeys != null) {
- boolean changed = false;
- for (String key : notificationKeys) {
- final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- synchronized (entry.mActiveAppOps) {
- if (active) {
- changed |= entry.mActiveAppOps.add(appOpCode);
- } else {
- changed |= entry.mActiveAppOps.remove(appOpCode);
- }
- }
- }
- }
- if (changed) {
- mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
- }
- }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index bb44583..1515272 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -172,24 +172,8 @@
sbn.getPackageName(), sbn.getKey());
}
}
- tagAppOps(entry);
return true;
},
true /* create if not found */);
}
-
- // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // AppOpsCoordinator
- private void tagAppOps(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
- sbn.getUserId(),
- sbn.getPackageName());
- synchronized (entry.mActiveAppOps) {
- entry.mActiveAppOps.clear();
- if (activeOps != null) {
- entry.mActiveAppOps.addAll(activeOps);
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java
index 7e5b426..93a8df4 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java
@@ -25,7 +25,9 @@
private int mUid;
private String mPackageName;
private long mTimeStarted;
- private String mState;
+ private StringBuilder mState;
+ // This is only used for items with mCode == AppOpsManager.OP_RECORD_AUDIO
+ private boolean mSilenced;
public AppOpItem(int code, int uid, String packageName, long timeStarted) {
this.mCode = code;
@@ -36,9 +38,8 @@
.append("AppOpItem(")
.append("Op code=").append(code).append(", ")
.append("UID=").append(uid).append(", ")
- .append("Package name=").append(packageName)
- .append(")")
- .toString();
+ .append("Package name=").append(packageName).append(", ")
+ .append("Paused=");
}
public int getCode() {
@@ -57,8 +58,16 @@
return mTimeStarted;
}
+ public void setSilenced(boolean silenced) {
+ mSilenced = silenced;
+ }
+
+ public boolean isSilenced() {
+ return mSilenced;
+ }
+
@Override
public String toString() {
- return mState;
+ return mState.append(mSilenced).append(")").toString();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index ce8e285..64b35ca 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -19,12 +19,16 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.media.AudioManager;
+import android.media.AudioRecordingConfiguration;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.SparseArray;
import androidx.annotation.WorkerThread;
@@ -62,6 +66,14 @@
private static final boolean DEBUG = false;
private final AppOpsManager mAppOps;
+ private final AudioManager mAudioManager;
+ private final LocationManager mLocationManager;
+
+ // mLocationProviderPackages are cached and updated only occasionally
+ private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000;
+ private long mLastLocationProviderPackageUpdate;
+ private List<String> mLocationProviderPackages;
+
private H mBGHandler;
private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>();
@@ -72,11 +84,16 @@
private final List<AppOpItem> mActiveItems = new ArrayList<>();
@GuardedBy("mNotedItems")
private final List<AppOpItem> mNotedItems = new ArrayList<>();
+ @GuardedBy("mActiveItems")
+ private final SparseArray<ArrayList<AudioRecordingConfiguration>> mRecordingsByUid =
+ new SparseArray<>();
protected static final int[] OPS = new int[] {
AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION
};
@@ -86,7 +103,8 @@
Context context,
@Background Looper bgLooper,
DumpManager dumpManager,
- PermissionFlagsCache cache
+ PermissionFlagsCache cache,
+ AudioManager audioManager
) {
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mFlagsCache = cache;
@@ -95,6 +113,8 @@
for (int i = 0; i < numOps; i++) {
mCallbacksByCode.put(OPS[i], new ArraySet<>());
}
+ mAudioManager = audioManager;
+ mLocationManager = context.getSystemService(LocationManager.class);
dumpManager.registerDumpable(TAG, this);
}
@@ -109,12 +129,19 @@
if (listening) {
mAppOps.startWatchingActive(OPS, this);
mAppOps.startWatchingNoted(OPS, this);
+ mAudioManager.registerAudioRecordingCallback(mAudioRecordingCallback, mBGHandler);
+ mBGHandler.post(() -> mAudioRecordingCallback.onRecordingConfigChanged(
+ mAudioManager.getActiveRecordingConfigurations()));
+
} else {
mAppOps.stopWatchingActive(this);
mAppOps.stopWatchingNoted(this);
+ mAudioManager.unregisterAudioRecordingCallback(mAudioRecordingCallback);
+
mBGHandler.removeCallbacksAndMessages(null); // null removes all
synchronized (mActiveItems) {
mActiveItems.clear();
+ mRecordingsByUid.clear();
}
synchronized (mNotedItems) {
mNotedItems.clear();
@@ -187,9 +214,12 @@
AppOpItem item = getAppOpItemLocked(mActiveItems, code, uid, packageName);
if (item == null && active) {
item = new AppOpItem(code, uid, packageName, System.currentTimeMillis());
+ if (code == AppOpsManager.OP_RECORD_AUDIO) {
+ item.setSilenced(isAnyRecordingPausedLocked(uid));
+ }
mActiveItems.add(item);
if (DEBUG) Log.w(TAG, "Added item: " + item.toString());
- return true;
+ return !item.isSilenced();
} else if (item != null && !active) {
mActiveItems.remove(item);
if (DEBUG) Log.w(TAG, "Removed item: " + item.toString());
@@ -213,7 +243,7 @@
active = getAppOpItemLocked(mActiveItems, code, uid, packageName) != null;
}
if (!active) {
- notifySuscribers(code, uid, packageName, false);
+ notifySuscribersWorker(code, uid, packageName, false);
}
}
@@ -268,6 +298,26 @@
return isUserVisible(item.getCode(), item.getUid(), item.getPackageName());
}
+ /**
+ * Checks if a package is the current location provider.
+ *
+ * <p>Data is cached to avoid too many calls into system server
+ *
+ * @param packageName The package that might be the location provider
+ *
+ * @return {@code true} iff the package is the location provider.
+ */
+ private boolean isLocationProvider(String packageName) {
+ long now = System.currentTimeMillis();
+
+ if (mLastLocationProviderPackageUpdate + LOCATION_PROVIDER_UPDATE_FREQUENCY_MS < now) {
+ mLastLocationProviderPackageUpdate = now;
+ mLocationProviderPackages = mLocationManager.getProviderPackages(
+ LocationManager.FUSED_PROVIDER);
+ }
+
+ return mLocationProviderPackages.contains(packageName);
+ }
/**
* Does the app-op, uid and package name, refer to an operation that should be shown to the
@@ -279,9 +329,17 @@
* @return {@code true} iff the app-op for should be shown to the user
*/
private boolean isUserVisible(int appOpCode, int uid, String packageName) {
- // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission
- // which may be user senstive, so for now always show it to the user.
- if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) {
+ // currently OP_SYSTEM_ALERT_WINDOW and OP_MONITOR_HIGH_POWER_LOCATION
+ // does not correspond to a platform permission
+ // which may be user sensitive, so for now always show it to the user.
+ if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW
+ || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION
+ || appOpCode == AppOpsManager.OP_PHONE_CALL_CAMERA
+ || appOpCode == AppOpsManager.OP_PHONE_CALL_MICROPHONE) {
+ return true;
+ }
+
+ if (appOpCode == AppOpsManager.OP_CAMERA && isLocationProvider(packageName)) {
return true;
}
@@ -319,7 +377,7 @@
AppOpItem item = mActiveItems.get(i);
if ((userId == UserHandle.USER_ALL
|| UserHandle.getUserId(item.getUid()) == userId)
- && isUserVisible(item)) {
+ && isUserVisible(item) && !item.isSilenced()) {
list.add(item);
}
}
@@ -338,6 +396,10 @@
return list;
}
+ private void notifySuscribers(int code, int uid, String packageName, boolean active) {
+ mBGHandler.post(() -> notifySuscribersWorker(code, uid, packageName, active));
+ }
+
@Override
public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
if (DEBUG) {
@@ -355,7 +417,7 @@
// If active is false, we only send the update if the op is not actively noted (prevent
// early removal)
if (!alsoNoted) {
- mBGHandler.post(() -> notifySuscribers(code, uid, packageName, active));
+ notifySuscribers(code, uid, packageName, active);
}
}
@@ -373,11 +435,11 @@
alsoActive = getAppOpItemLocked(mActiveItems, code, uid, packageName) != null;
}
if (!alsoActive) {
- mBGHandler.post(() -> notifySuscribers(code, uid, packageName, true));
+ notifySuscribers(code, uid, packageName, true);
}
}
- private void notifySuscribers(int code, int uid, String packageName, boolean active) {
+ private void notifySuscribersWorker(int code, int uid, String packageName, boolean active) {
if (mCallbacksByCode.containsKey(code) && isUserVisible(code, uid, packageName)) {
if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName);
for (Callback cb: mCallbacksByCode.get(code)) {
@@ -403,6 +465,61 @@
}
+ private boolean isAnyRecordingPausedLocked(int uid) {
+ List<AudioRecordingConfiguration> configs = mRecordingsByUid.get(uid);
+ if (configs == null) return false;
+ int configsNum = configs.size();
+ for (int i = 0; i < configsNum; i++) {
+ AudioRecordingConfiguration config = configs.get(i);
+ if (config.isClientSilenced()) return true;
+ }
+ return false;
+ }
+
+ private void updateRecordingPausedStatus() {
+ synchronized (mActiveItems) {
+ int size = mActiveItems.size();
+ for (int i = 0; i < size; i++) {
+ AppOpItem item = mActiveItems.get(i);
+ if (item.getCode() == AppOpsManager.OP_RECORD_AUDIO) {
+ boolean paused = isAnyRecordingPausedLocked(item.getUid());
+ if (item.isSilenced() != paused) {
+ item.setSilenced(paused);
+ notifySuscribers(
+ item.getCode(),
+ item.getUid(),
+ item.getPackageName(),
+ !item.isSilenced()
+ );
+ }
+ }
+ }
+ }
+ }
+
+ private AudioManager.AudioRecordingCallback mAudioRecordingCallback =
+ new AudioManager.AudioRecordingCallback() {
+ @Override
+ public void onRecordingConfigChanged(List<AudioRecordingConfiguration> configs) {
+ synchronized (mActiveItems) {
+ mRecordingsByUid.clear();
+ final int recordingsCount = configs.size();
+ for (int i = 0; i < recordingsCount; i++) {
+ AudioRecordingConfiguration recording = configs.get(i);
+
+ ArrayList<AudioRecordingConfiguration> recordings = mRecordingsByUid.get(
+ recording.getClientUid());
+ if (recordings == null) {
+ recordings = new ArrayList<>();
+ mRecordingsByUid.put(recording.getClientUid(), recordings);
+ }
+ recordings.add(recording);
+ }
+ }
+ updateRecordingPausedStatus();
+ }
+ };
+
protected class H extends Handler {
H(Looper looper) {
super(looper);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
index 8b953fa..be089b1 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
@@ -21,7 +21,7 @@
enum class AssistantSessionEvent(private val id: Int) : UiEventLogger.UiEventEnum {
@UiEvent(doc = "Unknown assistant session event")
- ASSISTANT_SESSION_UNKNOWN(523),
+ ASSISTANT_SESSION_UNKNOWN(0),
@UiEvent(doc = "Assistant session dismissed due to timeout")
ASSISTANT_SESSION_TIMEOUT_DISMISS(524),
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 3d29037..2948b47 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -134,7 +134,8 @@
@IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE,
DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT,
- DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED})
+ DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED,
+ DISMISS_NO_BUBBLE_UP})
@Target({FIELD, LOCAL_VARIABLE, PARAMETER})
@interface DismissReason {}
@@ -151,6 +152,7 @@
static final int DISMISS_OVERFLOW_MAX_REACHED = 11;
static final int DISMISS_SHORTCUT_REMOVED = 12;
static final int DISMISS_PACKAGE_REMOVED = 13;
+ static final int DISMISS_NO_BUBBLE_UP = 14;
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
@@ -1243,8 +1245,18 @@
rankingMap.getRanking(key, mTmpRanking);
boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
if (isActiveBubble && !mTmpRanking.canBubble()) {
- mBubbleData.dismissBubbleWithKey(entry.getKey(),
- BubbleController.DISMISS_BLOCKED);
+ // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason.
+ // This means that the app or channel's ability to bubble has been revoked.
+ mBubbleData.dismissBubbleWithKey(
+ key, BubbleController.DISMISS_BLOCKED);
+ } else if (isActiveBubble
+ && !mNotificationInterruptStateProvider.shouldBubbleUp(entry)) {
+ // If this entry is allowed to bubble, but cannot currently bubble up, dismiss it.
+ // This happens when DND is enabled and configured to hide bubbles. Dismissing with
+ // the reason DISMISS_NO_BUBBLE_UP will retain the underlying notification, so that
+ // the bubble will be re-created if shouldBubbleUp returns true.
+ mBubbleData.dismissBubbleWithKey(
+ key, BubbleController.DISMISS_NO_BUBBLE_UP);
} else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
entry.setFlagBubble(true);
onEntryUpdated(entry);
@@ -1321,8 +1333,10 @@
mStackView.removeBubble(bubble);
}
- // If the bubble is removed for user switching, leave the notification in place.
- if (reason == DISMISS_USER_CHANGED) {
+ // Leave the notification in place if we're dismissing due to user switching, or
+ // because DND is suppressing the bubble. In both of those cases, we need to be able
+ // to restore the bubble from the notification later.
+ if (reason == DISMISS_USER_CHANGED || reason == DISMISS_NO_BUBBLE_UP) {
continue;
}
if (reason == DISMISS_NOTIF_CANCEL) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 3d31712..1e556a3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -306,7 +306,6 @@
// Set ActivityView's alpha value as zero, since there is no view content to be shown.
setContentVisibility(false);
- mActivityViewContainer.setBackgroundColor(Color.WHITE);
mActivityViewContainer.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
@@ -434,9 +433,11 @@
}
void applyThemeAttrs() {
- final TypedArray ta = mContext.obtainStyledAttributes(
- new int[] {android.R.attr.dialogCornerRadius});
+ final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
+ android.R.attr.dialogCornerRadius,
+ android.R.attr.colorBackgroundFloating});
mCornerRadius = ta.getDimensionPixelSize(0, 0);
+ mActivityViewContainer.setBackgroundColor(ta.getColor(1, Color.WHITE));
ta.recycle();
if (mActivityView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt b/packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
new file mode 100644
index 0000000..cca0f16
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.controls
+
+import android.content.ComponentName
+import android.graphics.drawable.Icon
+import androidx.annotation.GuardedBy
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Icon cache for custom icons sent with controls.
+ *
+ * It assumes that only one component can be current at the time, to minimize the number of icons
+ * stored at a given time.
+ */
+@Singleton
+class CustomIconCache @Inject constructor() {
+
+ private var currentComponent: ComponentName? = null
+ @GuardedBy("cache")
+ private val cache: MutableMap<String, Icon> = LinkedHashMap()
+
+ /**
+ * Store an icon in the cache.
+ *
+ * If the icons currently stored do not correspond to the component to be stored, the cache is
+ * cleared first.
+ */
+ fun store(component: ComponentName, controlId: String, icon: Icon?) {
+ if (component != currentComponent) {
+ clear()
+ currentComponent = component
+ }
+ synchronized(cache) {
+ if (icon != null) {
+ cache.put(controlId, icon)
+ } else {
+ cache.remove(controlId)
+ }
+ }
+ }
+
+ /**
+ * Retrieves a custom icon stored in the cache.
+ *
+ * It will return null if the component requested is not the one whose icons are stored, or if
+ * there is no icon cached for that id.
+ */
+ fun retrieve(component: ComponentName, controlId: String): Icon? {
+ if (component != currentComponent) return null
+ return synchronized(cache) {
+ cache.get(controlId)
+ }
+ }
+
+ private fun clear() {
+ synchronized(cache) {
+ cache.clear()
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index c683a87..31830b9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -72,8 +72,13 @@
TYPE_CONTROL -> {
ControlHolder(
layoutInflater.inflate(R.layout.controls_base_item, parent, false).apply {
- layoutParams.apply {
+ (layoutParams as ViewGroup.MarginLayoutParams).apply {
width = ViewGroup.LayoutParams.MATCH_PARENT
+ // Reset margins as they will be set through the decoration
+ topMargin = 0
+ bottomMargin = 0
+ leftMargin = 0
+ rightMargin = 0
}
elevation = this@ControlAdapter.elevation
background = parent.context.getDrawable(
@@ -386,7 +391,7 @@
val type = parent.adapter?.getItemViewType(position)
if (type == ControlAdapter.TYPE_CONTROL) {
outRect.apply {
- top = topMargin
+ top = topMargin * 2 // Use double margin, as we are not setting bottom
left = sideMargins
right = sideMargins
bottom = 0
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index ff40a8a..f68388d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -29,6 +29,7 @@
import androidx.recyclerview.widget.RecyclerView
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.globalactions.GlobalActionsComponent
@@ -42,7 +43,8 @@
class ControlsEditingActivity @Inject constructor(
private val controller: ControlsControllerImpl,
broadcastDispatcher: BroadcastDispatcher,
- private val globalActionsComponent: GlobalActionsComponent
+ private val globalActionsComponent: GlobalActionsComponent,
+ private val customIconCache: CustomIconCache
) : LifecycleActivity() {
companion object {
@@ -170,7 +172,7 @@
private fun setUpList() {
val controls = controller.getFavoritesForStructure(component, structure)
- model = FavoritesModel(component, controls, favoritesModelCallback)
+ model = FavoritesModel(customIconCache, component, controls, favoritesModelCallback)
val elevation = resources.getFloat(R.dimen.control_card_elevation)
val recyclerView = requireViewById<RecyclerView>(R.id.list)
recyclerView.alpha = 0.0f
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
index 4ef64a5..ad0e7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
@@ -114,11 +114,27 @@
val controlStatus: ControlStatus
) : ElementWrapper(), ControlInterface by controlStatus
+private fun nullIconGetter(_a: ComponentName, _b: String): Icon? = null
+
data class ControlInfoWrapper(
override val component: ComponentName,
val controlInfo: ControlInfo,
override var favorite: Boolean
) : ElementWrapper(), ControlInterface {
+
+ var customIconGetter: (ComponentName, String) -> Icon? = ::nullIconGetter
+ private set
+
+ // Separate constructor so the getter is not used in auto-generated methods
+ constructor(
+ component: ComponentName,
+ controlInfo: ControlInfo,
+ favorite: Boolean,
+ customIconGetter: (ComponentName, String) -> Icon?
+ ): this(component, controlInfo, favorite) {
+ this.customIconGetter = customIconGetter
+ }
+
override val controlId: String
get() = controlInfo.controlId
override val title: CharSequence
@@ -128,8 +144,7 @@
override val deviceType: Int
get() = controlInfo.deviceType
override val customIcon: Icon?
- // Will need to address to support for edit activity
- get() = null
+ get() = customIconGetter(component, controlId)
}
data class DividerWrapper(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
index 5242501..f9ce636 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
@@ -21,6 +21,7 @@
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.android.systemui.controls.ControlInterface
+import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlInfo
import java.util.Collections
@@ -35,6 +36,7 @@
* @property favoritesModelCallback callback to notify on first change and empty favorites
*/
class FavoritesModel(
+ private val customIconCache: CustomIconCache,
private val componentName: ComponentName,
favorites: List<ControlInfo>,
private val favoritesModelCallback: FavoritesModelCallback
@@ -83,7 +85,7 @@
}
override val elements: List<ElementWrapper> = favorites.map {
- ControlInfoWrapper(componentName, it, true)
+ ControlInfoWrapper(componentName, it, true, customIconCache::retrieve)
} + DividerWrapper()
/**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 1eb7e21..5f75c96 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -44,6 +44,7 @@
import android.widget.TextView
import com.android.systemui.R
import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.controller.StructureInfo
@@ -75,7 +76,8 @@
@Main val sharedPreferences: SharedPreferences,
val controlActionCoordinator: ControlActionCoordinator,
private val activityStarter: ActivityStarter,
- private val shadeController: ShadeController
+ private val shadeController: ShadeController,
+ private val iconCache: CustomIconCache
) : ControlsUiController {
companion object {
@@ -502,6 +504,7 @@
controls.forEach { c ->
controlsById.get(ControlKey(componentName, c.getControlId()))?.let {
Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId())
+ iconCache.store(componentName, c.controlId, c.customIcon)
val cws = ControlWithState(componentName, it.ci, c)
val key = ControlKey(componentName, c.getControlId())
controlsById.put(key, cws)
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index ef51abb..0554dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -148,6 +148,7 @@
import java.util.concurrent.Executor;
import javax.inject.Inject;
+import javax.inject.Provider;
/**
* Helper to show the global actions dialog. Each item is an {@link Action} that may show depending
@@ -401,7 +402,7 @@
if (mDialog != null) {
if (!mDialog.isShowingControls() && shouldShowControls()) {
mDialog.showControls(mControlsUiControllerOptional.get());
- } else if (shouldShowLockMessage()) {
+ } else if (shouldShowLockMessage(mDialog)) {
mDialog.showLockMessage();
}
}
@@ -698,19 +699,17 @@
mPowerAdapter = new MyPowerOptionsAdapter();
mDepthController.setShowingHomeControls(true);
- GlobalActionsPanelPlugin.PanelViewController walletViewController =
- getWalletViewController();
ControlsUiController uiController = null;
if (mControlsUiControllerOptional.isPresent() && shouldShowControls()) {
uiController = mControlsUiControllerOptional.get();
}
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mOverflowAdapter,
- walletViewController, mDepthController, mSysuiColorExtractor,
+ this::getWalletViewController, mDepthController, mSysuiColorExtractor,
mStatusBarService, mNotificationShadeWindowController,
controlsAvailable(), uiController,
mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter);
- if (shouldShowLockMessage()) {
+ if (shouldShowLockMessage(dialog)) {
dialog.showLockMessage();
}
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
@@ -2124,7 +2123,8 @@
private MultiListLayout mGlobalActionsLayout;
private Drawable mBackgroundDrawable;
private final SysuiColorExtractor mColorExtractor;
- private final GlobalActionsPanelPlugin.PanelViewController mWalletViewController;
+ private final Provider<GlobalActionsPanelPlugin.PanelViewController> mWalletFactory;
+ @Nullable private GlobalActionsPanelPlugin.PanelViewController mWalletViewController;
private boolean mKeyguardShowing;
private boolean mShowing;
private float mScrimAlpha;
@@ -2144,7 +2144,7 @@
private TextView mLockMessage;
ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter,
- GlobalActionsPanelPlugin.PanelViewController walletViewController,
+ Provider<GlobalActionsPanelPlugin.PanelViewController> walletFactory,
NotificationShadeDepthController depthController,
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
@@ -2165,6 +2165,7 @@
mSysUiState = sysuiState;
mOnRotateCallback = onRotateCallback;
mKeyguardShowing = keyguardShowing;
+ mWalletFactory = walletFactory;
// Window initialization
Window window = getWindow();
@@ -2187,7 +2188,6 @@
window.getAttributes().setFitInsetsTypes(0 /* types */);
setTitle(R.string.global_actions);
- mWalletViewController = walletViewController;
initializeLayout();
}
@@ -2200,8 +2200,13 @@
mControlsUiController.show(mControlsView, this::dismissForControlsActivity);
}
+ private boolean isWalletViewAvailable() {
+ return mWalletViewController != null && mWalletViewController.getPanelContent() != null;
+ }
+
private void initializeWalletView() {
- if (mWalletViewController == null || mWalletViewController.getPanelContent() == null) {
+ mWalletViewController = mWalletFactory.get();
+ if (!isWalletViewAvailable()) {
return;
}
@@ -2507,6 +2512,8 @@
private void dismissWallet() {
if (mWalletViewController != null) {
mWalletViewController.onDismissed();
+ // The wallet controller should not be re-used after being dismissed.
+ mWalletViewController = null;
}
}
@@ -2648,18 +2655,12 @@
&& !mControlsServiceInfos.isEmpty();
}
- private boolean walletViewAvailable() {
- GlobalActionsPanelPlugin.PanelViewController walletViewController =
- getWalletViewController();
- return walletViewController != null && walletViewController.getPanelContent() != null;
- }
-
- private boolean shouldShowLockMessage() {
+ private boolean shouldShowLockMessage(ActionsDialog dialog) {
boolean isLockedAfterBoot = mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id)
== STRONG_AUTH_REQUIRED_AFTER_BOOT;
return !mKeyguardStateController.isUnlocked()
&& (!mShowLockScreenCardsAndControls || isLockedAfterBoot)
- && (controlsAvailable() || walletViewAvailable());
+ && (controlsAvailable() || dialog.isWalletViewAvailable());
}
private void onPowerMenuLockScreenSettingsChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 3a84123..15c6092 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -151,7 +151,7 @@
pageIndicator = mediaFrame.requireViewById(R.id.media_page_indicator)
mediaCarouselScrollHandler = MediaCarouselScrollHandler(mediaCarousel, pageIndicator,
executor, mediaManager::onSwipeToDismiss, this::updatePageIndicatorLocation,
- falsingManager)
+ this::closeGuts, falsingManager)
isRtl = context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
inflateSettingsButton()
mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
@@ -470,6 +470,12 @@
}
}
+ fun closeGuts() {
+ mediaPlayers.values.forEach {
+ it.closeGuts(true)
+ }
+ }
+
/**
* Update the size of the carousel, remeasuring it if necessary.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
index 3096908..77cac50 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
@@ -56,6 +56,7 @@
private val mainExecutor: DelayableExecutor,
private val dismissCallback: () -> Unit,
private var translationChangedListener: () -> Unit,
+ private val closeGuts: () -> Unit,
private val falsingManager: FalsingManager
) {
/**
@@ -452,6 +453,7 @@
val nowScrolledIn = scrollIntoCurrentMedia != 0
if (newIndex != activeMediaIndex || wasScrolledIn != nowScrolledIn) {
activeMediaIndex = newIndex
+ closeGuts()
updatePlayerVisibilities()
}
val relativeLocation = activeMediaIndex.toFloat() + if (playerWidthPlusPadding > 0)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 3fc162e..e55678dc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -16,6 +16,8 @@
package com.android.systemui.media;
+import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
+
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -45,6 +47,7 @@
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.util.animation.TransitionLayout;
import java.util.List;
@@ -52,6 +55,8 @@
import javax.inject.Inject;
+import dagger.Lazy;
+
/**
* A view controller used for Media Playback.
*/
@@ -59,6 +64,8 @@
private static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
+ private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS);
+
// Button IDs for QS controls
static final int[] ACTION_IDS = {
R.id.action0,
@@ -78,6 +85,8 @@
private MediaViewController mMediaViewController;
private MediaSession.Token mToken;
private MediaController mController;
+ private KeyguardDismissUtil mKeyguardDismissUtil;
+ private Lazy<MediaDataManager> mMediaDataManagerLazy;
private int mBackgroundColor;
private int mAlbumArtSize;
private int mAlbumArtRadius;
@@ -93,12 +102,15 @@
@Inject
public MediaControlPanel(Context context, @Background Executor backgroundExecutor,
ActivityStarter activityStarter, MediaViewController mediaViewController,
- SeekBarViewModel seekBarViewModel) {
+ SeekBarViewModel seekBarViewModel, Lazy<MediaDataManager> lazyMediaDataManager,
+ KeyguardDismissUtil keyguardDismissUtil) {
mContext = context;
mBackgroundExecutor = backgroundExecutor;
mActivityStarter = activityStarter;
mSeekBarViewModel = seekBarViewModel;
mMediaViewController = mediaViewController;
+ mMediaDataManagerLazy = lazyMediaDataManager;
+ mKeyguardDismissUtil = keyguardDismissUtil;
loadDimens();
mViewOutlineProvider = new ViewOutlineProvider() {
@@ -174,6 +186,21 @@
mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
mMediaViewController.attach(player);
+
+ mViewHolder.getPlayer().setOnLongClickListener(v -> {
+ if (!mMediaViewController.isGutsVisible()) {
+ mMediaViewController.openGuts();
+ return true;
+ } else {
+ return false;
+ }
+ });
+ mViewHolder.getCancel().setOnClickListener(v -> {
+ closeGuts();
+ });
+ mViewHolder.getSettings().setOnClickListener(v -> {
+ mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
+ });
}
/**
@@ -205,6 +232,7 @@
PendingIntent clickIntent = data.getClickIntent();
if (clickIntent != null) {
mViewHolder.getPlayer().setOnClickListener(v -> {
+ if (mMediaViewController.isGutsVisible()) return;
mActivityStarter.postStartActivityDismissingKeyguard(clickIntent);
});
}
@@ -329,14 +357,38 @@
final MediaController controller = getController();
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
- // Set up long press menu
- // TODO: b/156036025 bring back media guts
+ // Dismiss
+ mViewHolder.getDismiss().setOnClickListener(v -> {
+ if (data.getNotificationKey() != null) {
+ closeGuts();
+ mKeyguardDismissUtil.executeWhenUnlocked(() -> {
+ mMediaDataManagerLazy.get().dismissMediaData(data.getNotificationKey(),
+ MediaViewController.GUTS_ANIMATION_DURATION + 100);
+ return true;
+ }, /* requiresShadeOpen */ true);
+ } else {
+ Log.w(TAG, "Dismiss media with null notification. Token uid="
+ + data.getToken().getUid());
+ }
+ });
// TODO: We don't need to refresh this state constantly, only if the state actually changed
// to something which might impact the measurement
mMediaViewController.refreshState();
}
+ /**
+ * Close the guts for this player.
+ * @param immediate {@code true} if it should be closed without animation
+ */
+ public void closeGuts(boolean immediate) {
+ mMediaViewController.closeGuts(immediate);
+ }
+
+ private void closeGuts() {
+ closeGuts(false);
+ }
+
@UiThread
private Drawable scaleDrawable(Icon icon) {
if (icon == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index b327773..33475ac 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -48,12 +48,15 @@
import com.android.systemui.statusbar.notification.row.HybridGroupManager
import com.android.systemui.util.Assert
import com.android.systemui.util.Utils
+import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.FileDescriptor
import java.io.IOException
import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
+import kotlin.collections.ArrayList
+import kotlin.collections.LinkedHashMap
// URI fields to try loading album art from
private val ART_URIS = arrayOf(
@@ -89,7 +92,7 @@
class MediaDataManager(
private val context: Context,
@Background private val backgroundExecutor: Executor,
- @Main private val foregroundExecutor: Executor,
+ @Main private val foregroundExecutor: DelayableExecutor,
private val mediaControllerFactory: MediaControllerFactory,
private val broadcastDispatcher: BroadcastDispatcher,
dumpManager: DumpManager,
@@ -101,12 +104,23 @@
private val listeners: MutableSet<Listener> = mutableSetOf()
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
+ internal var appsBlockedFromResume: MutableSet<String> = Utils.getBlockedMediaApps(context)
+ set(value) {
+ // Update list
+ appsBlockedFromResume.clear()
+ appsBlockedFromResume.addAll(value)
+
+ // Remove any existing resume players that are now blocked
+ appsBlockedFromResume.forEach {
+ removeAllForPackage(it)
+ }
+ }
@Inject
constructor(
context: Context,
@Background backgroundExecutor: Executor,
- @Main foregroundExecutor: Executor,
+ @Main foregroundExecutor: DelayableExecutor,
mediaControllerFactory: MediaControllerFactory,
dumpManager: DumpManager,
broadcastDispatcher: BroadcastDispatcher,
@@ -182,10 +196,7 @@
val listenersCopy = listeners.toSet()
val toRemove = mediaEntries.filter { it.value.packageName == packageName }
toRemove.forEach {
- mediaEntries.remove(it.key)
- listenersCopy.forEach { listener ->
- listener.onMediaDataRemoved(it.key)
- }
+ removeEntry(it.key, listenersCopy)
}
}
@@ -267,6 +278,18 @@
}
}
+ private fun removeEntry(key: String, listenersCopy: Set<Listener>) {
+ mediaEntries.remove(key)
+ listenersCopy.forEach {
+ it.onMediaDataRemoved(key)
+ }
+ }
+
+ fun dismissMediaData(key: String, delay: Long) {
+ val listenersCopy = listeners.toSet()
+ foregroundExecutor.executeDelayed({ removeEntry(key, listenersCopy) }, delay)
+ }
+
private fun loadMediaDataInBgForResumption(
userId: Int,
desc: MediaDescription,
@@ -513,7 +536,8 @@
fun onNotificationRemoved(key: String) {
Assert.isMainThread()
val removed = mediaEntries.remove(key)
- if (useMediaResumption && removed?.resumeAction != null) {
+ if (useMediaResumption && removed?.resumeAction != null &&
+ !isBlockedFromResume(removed?.packageName)) {
Log.d(TAG, "Not removing $key because resumable")
// Move to resume key (aka package name) if that key doesn't already exist.
val resumeAction = getResumeMediaAction(removed.resumeAction!!)
@@ -550,6 +574,13 @@
}
}
+ private fun isBlockedFromResume(packageName: String?): Boolean {
+ if (packageName == null) {
+ return true
+ }
+ return appsBlockedFromResume.contains(packageName)
+ }
+
fun setMediaResumptionEnabled(isEnabled: Boolean) {
if (useMediaResumption == isEnabled) {
return
@@ -592,6 +623,7 @@
println("listeners: $listeners")
println("mediaEntries: $mediaEntries")
println("useMediaResumption: $useMediaResumption")
+ println("appsBlockedFromResume: $appsBlockedFromResume")
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index fc33391..b31390c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -293,6 +293,13 @@
return viewHost
}
+ /**
+ * Close the guts in all players in [MediaCarouselController].
+ */
+ fun closeGuts() {
+ mediaCarouselController.closeGuts()
+ }
+
private fun createUniqueObjectHost(): UniqueObjectHostView {
val viewHost = UniqueObjectHostView(context)
viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
@@ -382,6 +389,14 @@
if (isCurrentlyInGuidedTransformation()) {
return false
}
+ // This is an invalid transition, and can happen when using the camera gesture from the
+ // lock screen. Disallow.
+ if (previousLocation == LOCATION_LOCKSCREEN &&
+ desiredLocation == LOCATION_QQS &&
+ statusbarState == StatusBarState.SHADE) {
+ return false
+ }
+
if (currentLocation == LOCATION_QQS &&
previousLocation == LOCATION_LOCKSCREEN &&
(statusBarStateController.leaveOpenOnKeyguardHide() ||
@@ -597,8 +612,8 @@
// When collapsing on the lockscreen, we want to remain in QS
return LOCATION_QS
}
- if (location != LOCATION_LOCKSCREEN && desiredLocation == LOCATION_LOCKSCREEN
- && !fullyAwake) {
+ if (location != LOCATION_LOCKSCREEN && desiredLocation == LOCATION_LOCKSCREEN &&
+ !fullyAwake) {
// When unlocking from dozing / while waking up, the media shouldn't be transitioning
// in an animated way. Let's keep it in the lockscreen until we're fully awake and
// reattach it without an animation
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index 4ec746f..c41712c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -52,6 +52,7 @@
private var useMediaResumption: Boolean = Utils.useMediaResumption(context)
private val resumeComponents: ConcurrentLinkedQueue<ComponentName> = ConcurrentLinkedQueue()
+ private var blockedApps: MutableSet<String> = Utils.getBlockedMediaApps(context)
private lateinit var mediaDataManager: MediaDataManager
@@ -114,6 +115,14 @@
mediaDataManager.setMediaResumptionEnabled(useMediaResumption)
}
}, Settings.Secure.MEDIA_CONTROLS_RESUME)
+
+ // Listen to changes in which apps are allowed to persist
+ tunerService.addTunable(object : TunerService.Tunable {
+ override fun onTuningChanged(key: String?, newValue: String?) {
+ blockedApps = Utils.getBlockedMediaApps(context)
+ mediaDataManager.appsBlockedFromResume = blockedApps
+ }
+ }, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED)
}
fun isResumptionEnabled() = useMediaResumption
@@ -144,8 +153,10 @@
}
resumeComponents.forEach {
- val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it)
- browser.findRecentMedia()
+ if (!blockedApps.contains(it.packageName)) {
+ val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it)
+ browser.findRecentMedia()
+ }
}
}
@@ -154,7 +165,8 @@
// If this had been started from a resume state, disconnect now that it's live
mediaBrowser?.disconnect()
// If we don't have a resume action, check if we haven't already
- if (data.resumeAction == null && !data.hasCheckedForResume) {
+ if (data.resumeAction == null && !data.hasCheckedForResume &&
+ !blockedApps.contains(data.packageName)) {
// TODO also check for a media button receiver intended for restarting (b/154127084)
Log.d(TAG, "Checking for service component for " + data.packageName)
val pm = context.packageManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 38817d7..92eeed4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -37,6 +37,11 @@
private val mediaHostStatesManager: MediaHostStatesManager
) {
+ companion object {
+ @JvmField
+ val GUTS_ANIMATION_DURATION = 500L
+ }
+
/**
* A listener when the current dimensions of the player change
*/
@@ -169,6 +174,12 @@
*/
val expandedLayout = ConstraintSet()
+ /**
+ * Whether the guts are visible for the associated player.
+ */
+ var isGutsVisible = false
+ private set
+
init {
collapsedLayout.load(context, R.xml.media_collapsed)
expandedLayout.load(context, R.xml.media_expanded)
@@ -189,6 +200,37 @@
configurationController.removeCallback(configurationListener)
}
+ /**
+ * Show guts with an animated transition.
+ */
+ fun openGuts() {
+ if (isGutsVisible) return
+ isGutsVisible = true
+ animatePendingStateChange(GUTS_ANIMATION_DURATION, 0L)
+ setCurrentState(currentStartLocation,
+ currentEndLocation,
+ currentTransitionProgress,
+ applyImmediately = false)
+ }
+
+ /**
+ * Close the guts for the associated player.
+ *
+ * @param immediate if `false`, it will animate the transition.
+ */
+ @JvmOverloads
+ fun closeGuts(immediate: Boolean = false) {
+ if (!isGutsVisible) return
+ isGutsVisible = false
+ if (!immediate) {
+ animatePendingStateChange(GUTS_ANIMATION_DURATION, 0L)
+ }
+ setCurrentState(currentStartLocation,
+ currentEndLocation,
+ currentTransitionProgress,
+ applyImmediately = immediate)
+ }
+
private fun ensureAllMeasurements() {
val mediaStates = mediaHostStatesManager.mediaHostStates
for (entry in mediaStates) {
@@ -203,6 +245,24 @@
if (expansion > 0) expandedLayout else collapsedLayout
/**
+ * Set the views to be showing/hidden based on the [isGutsVisible] for a given
+ * [TransitionViewState].
+ */
+ private fun setGutsViewState(viewState: TransitionViewState) {
+ PlayerViewHolder.controlsIds.forEach { id ->
+ viewState.widgetStates.get(id)?.let { state ->
+ // Make sure to use the unmodified state if guts are not visible
+ state.alpha = if (isGutsVisible) 0f else state.alpha
+ state.gone = if (isGutsVisible) true else state.gone
+ }
+ }
+ PlayerViewHolder.gutsIds.forEach { id ->
+ viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f
+ viewState.widgetStates.get(id)?.gone = !isGutsVisible
+ }
+ }
+
+ /**
* Obtain a new viewState for a given media state. This usually returns a cached state, but if
* it's not available, it will recreate one by measuring, which may be expensive.
*/
@@ -211,7 +271,7 @@
return null
}
// Only a subset of the state is relevant to get a valid viewState. Let's get the cachekey
- var cacheKey = getKey(state, tmpKey)
+ var cacheKey = getKey(state, isGutsVisible, tmpKey)
val viewState = viewStates[cacheKey]
if (viewState != null) {
// we already have cached this measurement, let's continue
@@ -228,6 +288,7 @@
constraintSetForExpansion(state.expansion),
TransitionViewState())
+ setGutsViewState(result)
// We don't want to cache interpolated or null states as this could quickly fill up
// our cache. We only cache the start and the end states since the interpolation
// is cheap
@@ -252,11 +313,12 @@
return result
}
- private fun getKey(state: MediaHostState, result: CacheKey): CacheKey {
+ private fun getKey(state: MediaHostState, guts: Boolean, result: CacheKey): CacheKey {
result.apply {
heightMeasureSpec = state.measurementInput?.heightMeasureSpec ?: 0
widthMeasureSpec = state.measurementInput?.widthMeasureSpec ?: 0
expansion = state.expansion
+ gutsVisible = guts
}
return result
}
@@ -432,5 +494,6 @@
private data class CacheKey(
var widthMeasureSpec: Int = -1,
var heightMeasureSpec: Int = -1,
- var expansion: Float = 0.0f
+ var expansion: Float = 0.0f,
+ var gutsVisible: Boolean = false
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
index 600fdc2..666a603 100644
--- a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
@@ -59,6 +59,11 @@
val action3 = itemView.requireViewById<ImageButton>(R.id.action3)
val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
+ // Settings screen
+ val cancel = itemView.requireViewById<View>(R.id.cancel)
+ val dismiss = itemView.requireViewById<View>(R.id.dismiss)
+ val settings = itemView.requireViewById<View>(R.id.settings)
+
init {
(player.background as IlluminationDrawable).let {
it.registerLightSource(seamless)
@@ -67,6 +72,9 @@
it.registerLightSource(action2)
it.registerLightSource(action3)
it.registerLightSource(action4)
+ it.registerLightSource(cancel)
+ it.registerLightSource(dismiss)
+ it.registerLightSource(settings)
}
}
@@ -83,9 +91,6 @@
}
}
- // Settings screen
- val options = itemView.requireViewById<View>(R.id.qs_media_controls_options)
-
companion object {
/**
* Creates a PlayerViewHolder.
@@ -105,5 +110,29 @@
progressTimes.layoutDirection = View.LAYOUT_DIRECTION_LTR
}
}
+
+ val controlsIds = setOf(
+ R.id.icon,
+ R.id.app_name,
+ R.id.album_art,
+ R.id.header_title,
+ R.id.header_artist,
+ R.id.media_seamless,
+ R.id.notification_media_progress_time,
+ R.id.media_progress_bar,
+ R.id.action0,
+ R.id.action1,
+ R.id.action2,
+ R.id.action3,
+ R.id.action4,
+ R.id.icon
+ )
+ val gutsIds = setOf(
+ R.id.media_text,
+ R.id.remove_text,
+ R.id.cancel,
+ R.id.dismiss,
+ R.id.settings
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 8bbd15b..583953c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -177,7 +177,7 @@
}
if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
transformBoundsToAspectRatio(normalBounds, mAspectRatio,
- false /* useCurrentMinEdgeSize */);
+ false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
}
displayInfo.copyFrom(mDisplayInfo);
}
@@ -278,7 +278,9 @@
destinationBounds = new Rect(bounds);
}
if (isValidPictureInPictureAspectRatio(aspectRatio)) {
- transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize);
+ boolean useCurrentSize = bounds == null && mReentrySize != null;
+ transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize,
+ useCurrentSize);
}
mAspectRatio = aspectRatio;
return destinationBounds;
@@ -384,7 +386,8 @@
* @param stackBounds
*/
public void transformBoundsToAspectRatio(Rect stackBounds) {
- transformBoundsToAspectRatio(stackBounds, mAspectRatio, true);
+ transformBoundsToAspectRatio(stackBounds, mAspectRatio, true /* useCurrentMinEdgeSize */,
+ true /* useCurrentSize */);
}
/**
@@ -392,18 +395,16 @@
* specified aspect ratio.
*/
private void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
- boolean useCurrentMinEdgeSize) {
+ boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
// Save the snap fraction and adjust the size based on the new aspect ratio.
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
getMovementBounds(stackBounds));
- final int minEdgeSize;
+ final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
final Size size;
- if (useCurrentMinEdgeSize) {
- minEdgeSize = mCurrentMinSize;
+ if (useCurrentMinEdgeSize || useCurrentSize) {
size = mSnapAlgorithm.getSizeForAspectRatio(
new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
} else {
- minEdgeSize = mDefaultMinSize;
size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index c4152fa..8d4ca5e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -40,7 +40,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
@@ -99,11 +98,12 @@
private final Handler mUpdateHandler;
private final PipBoundsHandler mPipBoundsHandler;
private final PipAnimationController mPipAnimationController;
+ private final PipUiEventLogger mPipUiEventLoggerLogger;
private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
private final Rect mLastReportedBounds = new Rect();
private final int mEnterExitAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
- private final Map<IBinder, Configuration> mInitialState = new HashMap<>();
+ private final Map<IBinder, PipWindowConfigurationCompact> mCompactState = new HashMap<>();
private final Divider mSplitDivider;
// These callbacks are called on the update thread
@@ -201,12 +201,15 @@
*/
private boolean mShouldDeferEnteringPip;
+ private @ActivityInfo.ScreenOrientation int mRequestedOrientation;
+
@Inject
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
@Nullable Divider divider,
@NonNull DisplayController displayController,
- @NonNull PipAnimationController pipAnimationController) {
+ @NonNull PipAnimationController pipAnimationController,
+ @NonNull PipUiEventLogger pipUiEventLogger) {
mMainHandler = new Handler(Looper.getMainLooper());
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
mPipBoundsHandler = boundsHandler;
@@ -214,6 +217,7 @@
.getInteger(R.integer.config_pipResizeAnimationDuration);
mSurfaceTransactionHelper = surfaceTransactionHelper;
mPipAnimationController = pipAnimationController;
+ mPipUiEventLoggerLogger = pipUiEventLogger;
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
mSplitDivider = divider;
displayController.addDisplayWindowListener(this);
@@ -276,11 +280,15 @@
return;
}
- final Configuration initialConfig = mInitialState.remove(mToken.asBinder());
- final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation()
+ mPipUiEventLoggerLogger.log(
+ PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN);
+ final PipWindowConfigurationCompact config = mCompactState.remove(mToken.asBinder());
+ config.syncWithScreenOrientation(mRequestedOrientation,
+ mPipBoundsHandler.getDisplayRotation());
+ final boolean orientationDiffers = config.getRotation()
!= mPipBoundsHandler.getDisplayRotation();
final WindowContainerTransaction wct = new WindowContainerTransaction();
- final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
+ final Rect destinationBounds = config.getBounds();
final int direction = syncWithSplitScreenBounds(destinationBounds)
? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
: TRANSITION_DIRECTION_TO_FULLSCREEN;
@@ -346,7 +354,7 @@
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(mEnterExitAnimationDuration)
.start());
- mInitialState.remove(mToken.asBinder());
+ mCompactState.remove(mToken.asBinder());
mExitingPip = true;
}
@@ -372,8 +380,13 @@
mInPip = true;
mExitingPip = false;
mLeash = leash;
- mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
+ mCompactState.put(mToken.asBinder(),
+ new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration));
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
+ mRequestedOrientation = info.requestedOrientation;
+
+ mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);
+ mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER);
if (mShouldDeferEnteringPip) {
if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing");
@@ -507,11 +520,14 @@
mPictureInPictureParams = null;
mInPip = false;
mExitingPip = false;
+ mPipUiEventLoggerLogger.setTaskInfo(null);
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
+ mRequestedOrientation = info.requestedOrientation;
+ // check PictureInPictureParams for aspect ratio change.
final PictureInPictureParams newParams = info.pictureInPictureParams;
if (newParams == null || !applyPictureInPictureParams(newParams)) {
Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
@@ -549,8 +565,6 @@
}
/**
- * TODO(b/152809058): consolidate the display info handling logic in SysUI
- *
* @param destinationBoundsOut the current destination bounds will be populated to this param
*/
@SuppressWarnings("unchecked")
@@ -622,7 +636,7 @@
* {@link PictureInPictureParams} would affect the bounds.
*/
private boolean applyPictureInPictureParams(@NonNull PictureInPictureParams params) {
- final boolean changed = (mPictureInPictureParams == null) ? true : !Objects.equals(
+ final boolean changed = (mPictureInPictureParams == null) || !Objects.equals(
mPictureInPictureParams.getAspectRatioRational(), params.getAspectRatioRational());
if (changed) {
mPictureInPictureParams = params;
@@ -954,9 +968,9 @@
pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds);
pw.println(innerPrefix + "mInitialState:");
- for (Map.Entry<IBinder, Configuration> e : mInitialState.entrySet()) {
+ for (Map.Entry<IBinder, PipWindowConfigurationCompact> e : mCompactState.entrySet()) {
pw.println(innerPrefix + " binder=" + e.getKey()
- + " winConfig=" + e.getValue().windowConfiguration);
+ + " config=" + e.getValue());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java
new file mode 100644
index 0000000..5e2cd9c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java
@@ -0,0 +1,97 @@
+/*
+ * 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.pip;
+
+import android.app.TaskInfo;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+
+/**
+ * Helper class that ends PiP log to UiEvent, see also go/uievent
+ */
+@Singleton
+public class PipUiEventLogger {
+
+ private final UiEventLogger mUiEventLogger;
+
+ private TaskInfo mTaskInfo;
+
+ @Inject
+ public PipUiEventLogger(UiEventLogger uiEventLogger) {
+ mUiEventLogger = uiEventLogger;
+ }
+
+ public void setTaskInfo(TaskInfo taskInfo) {
+ mTaskInfo = taskInfo;
+ }
+
+ /**
+ * Sends log via UiEvent, reference go/uievent for how to debug locally
+ */
+ public void log(PipUiEventEnum event) {
+ if (mTaskInfo == null) {
+ return;
+ }
+ mUiEventLogger.log(event, mTaskInfo.userId, mTaskInfo.topActivity.getPackageName());
+ }
+
+ /**
+ * Enums for logging the PiP events to UiEvent
+ */
+ public enum PipUiEventEnum implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Activity enters picture-in-picture mode")
+ PICTURE_IN_PICTURE_ENTER(603),
+
+ @UiEvent(doc = "Expands from picture-in-picture to fullscreen")
+ PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604),
+
+ @UiEvent(doc = "Removes picture-in-picture by tap close button")
+ PICTURE_IN_PICTURE_TAP_TO_REMOVE(605),
+
+ @UiEvent(doc = "Removes picture-in-picture by drag to dismiss area")
+ PICTURE_IN_PICTURE_DRAG_TO_REMOVE(606),
+
+ @UiEvent(doc = "Shows picture-in-picture menu")
+ PICTURE_IN_PICTURE_SHOW_MENU(607),
+
+ @UiEvent(doc = "Hides picture-in-picture menu")
+ PICTURE_IN_PICTURE_HIDE_MENU(608),
+
+ @UiEvent(doc = "Changes the aspect ratio of picture-in-picture window. This is inherited"
+ + " from previous Tron-based logging and currently not in use.")
+ PICTURE_IN_PICTURE_CHANGE_ASPECT_RATIO(609),
+
+ @UiEvent(doc = "User resize of the picture-in-picture window")
+ PICTURE_IN_PICTURE_RESIZE(610);
+
+ private final int mId;
+
+ PipUiEventEnum(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java
new file mode 100644
index 0000000..ba104d6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java
@@ -0,0 +1,80 @@
+/*
+ * 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.pip;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
+import android.view.Surface;
+
+/**
+ * Compact {@link WindowConfiguration} for PiP usage and supports operations such as rotate.
+ */
+class PipWindowConfigurationCompact {
+ private @Surface.Rotation int mRotation;
+ private Rect mBounds;
+
+ PipWindowConfigurationCompact(WindowConfiguration windowConfiguration) {
+ mRotation = windowConfiguration.getRotation();
+ mBounds = windowConfiguration.getBounds();
+ }
+
+ @Surface.Rotation int getRotation() {
+ return mRotation;
+ }
+
+ Rect getBounds() {
+ return mBounds;
+ }
+
+ void syncWithScreenOrientation(@ActivityInfo.ScreenOrientation int screenOrientation,
+ @Surface.Rotation int displayRotation) {
+ if (mBounds.top != 0 || mBounds.left != 0) {
+ // Supports fullscreen bounds like (0, 0, width, height) only now.
+ return;
+ }
+ boolean rotateNeeded = false;
+ if (ActivityInfo.isFixedOrientationPortrait(screenOrientation)
+ && (mRotation == ROTATION_90 || mRotation == ROTATION_270)) {
+ mRotation = ROTATION_0;
+ rotateNeeded = true;
+ } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation)
+ && (mRotation == ROTATION_0 || mRotation == ROTATION_180)) {
+ mRotation = ROTATION_90;
+ rotateNeeded = true;
+ } else if (screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED
+ && mRotation != displayRotation) {
+ mRotation = displayRotation;
+ rotateNeeded = true;
+ }
+ if (rotateNeeded) {
+ mBounds.set(0, 0, mBounds.height(), mBounds.width());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "PipWindowConfigurationCompact(rotation=" + mRotation
+ + " bounds=" + mBounds + ")";
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 7d35416..9d9c5a6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -46,6 +46,7 @@
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.pip.PipUiEventLogger;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
@@ -229,7 +230,10 @@
@Override
public void onAspectRatioChanged(float aspectRatio) {
- mHandler.post(() -> mPipBoundsHandler.onAspectRatioChanged(aspectRatio));
+ mHandler.post(() -> {
+ mPipBoundsHandler.onAspectRatioChanged(aspectRatio);
+ mTouchHandler.onAspectRatioChanged();
+ });
}
}
@@ -241,7 +245,8 @@
PipBoundsHandler pipBoundsHandler,
PipSnapAlgorithm pipSnapAlgorithm,
PipTaskOrganizer pipTaskOrganizer,
- SysUiState sysUiState) {
+ SysUiState sysUiState,
+ PipUiEventLogger pipUiEventLogger) {
mContext = context;
mActivityManager = ActivityManager.getService();
@@ -262,7 +267,8 @@
mInputConsumerController);
mTouchHandler = new PipTouchHandler(context, mActivityManager,
mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
- floatingContentCoordinator, deviceConfig, pipSnapAlgorithm, sysUiState);
+ floatingContentCoordinator, deviceConfig, pipSnapAlgorithm, sysUiState,
+ pipUiEventLogger);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
mTouchHandler.getMotionHelper());
displayController.addDisplayChangingController(mRotationController);
@@ -355,17 +361,8 @@
@Override
public void onPipTransitionStarted(ComponentName activity, int direction) {
if (isOutPipDirection(direction)) {
- // On phones, the expansion animation that happens on pip tap before restoring
- // to fullscreen makes it so that the bounds received here are the expanded
- // bounds. We want to restore to the unexpanded bounds when re-entering pip,
- // so we save the bounds before expansion (normal) instead of the current
- // bounds.
- mReentryBounds.set(mTouchHandler.getNormalBounds());
- // Apply the snap fraction of the current bounds to the normal bounds.
- final Rect bounds = mPipTaskOrganizer.getLastReportedBounds();
- float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
- mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction);
- // Save reentry bounds (normal non-expand bounds with current position applied).
+ // Exiting PIP, save the reentry bounds to restore to when re-entering.
+ updateReentryBounds();
mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds);
}
// Disable touches while the animation is running
@@ -379,6 +376,18 @@
}
}
+ /**
+ * Update the bounds used to save the re-entry size and snap fraction when exiting PIP.
+ */
+ public void updateReentryBounds() {
+ final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
+ // Apply the snap fraction of the current bounds to the normal bounds.
+ final Rect bounds = mPipTaskOrganizer.getLastReportedBounds();
+ float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
+ mPipBoundsHandler.applySnapFraction(reentryBounds, snapFraction);
+ mReentryBounds.set(reentryBounds);
+ }
+
@Override
public void onPipTransitionFinished(ComponentName activity, int direction) {
onPipTransitionFinishedOrCanceled(direction);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 8a2e4ae..9f0b1de 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -26,9 +26,10 @@
import android.util.Log;
import android.view.Choreographer;
+import androidx.dynamicanimation.animation.AnimationHandler;
+import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.util.FloatingContentCoordinator;
@@ -74,9 +75,6 @@
/** The region that all of PIP must stay within. */
private final Rect mFloatingAllowedArea = new Rect();
- private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider =
- new SfVsyncFrameCallbackProvider();
-
/**
* Temporary bounds used when PIP is being dragged or animated. These bounds are applied to PIP
* using {@link PipTaskOrganizer#scheduleUserResizePip}, so that we can animate shrinking into
@@ -94,8 +92,13 @@
/** Coordinator instance for resolving conflicts with other floating content. */
private FloatingContentCoordinator mFloatingContentCoordinator;
- /** Callback that re-sizes PIP to the animated bounds. */
- private final Choreographer.FrameCallback mResizePipVsyncCallback;
+ private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
+ ThreadLocal.withInitial(() -> {
+ FrameCallbackScheduler scheduler = runnable ->
+ Choreographer.getSfInstance().postFrameCallback(t -> runnable.run());
+ AnimationHandler handler = new AnimationHandler(scheduler);
+ return handler;
+ });
/**
* PhysicsAnimator instance for animating {@link #mTemporaryBounds} using physics animations.
@@ -171,16 +174,15 @@
mSnapAlgorithm = snapAlgorithm;
mFloatingContentCoordinator = floatingContentCoordinator;
mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
+ mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler(
+ mSfAnimationHandlerThreadLocal.get());
- mResizePipVsyncCallback = l -> {
+ mResizePipUpdateListener = (target, values) -> {
if (!mTemporaryBounds.isEmpty()) {
mPipTaskOrganizer.scheduleUserResizePip(
mBounds, mTemporaryBounds, null);
}
};
-
- mResizePipUpdateListener = (target, values) ->
- mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback);
}
@NonNull
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index 1ca53f9..ef73aa7 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -53,12 +53,12 @@
import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.pip.PipUiEventLogger;
import com.android.systemui.util.DeviceConfigProxy;
import java.io.PrintWriter;
import java.util.concurrent.Executor;
import java.util.function.Function;
-import java.util.function.Supplier;
/**
* Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to
@@ -89,6 +89,7 @@
private final Point mMaxSize = new Point();
private final Point mMinSize = new Point();
private final Rect mLastResizeBounds = new Rect();
+ private final Rect mUserResizeBounds = new Rect();
private final Rect mLastDownBounds = new Rect();
private final Rect mDragCornerSize = new Rect();
private final Rect mTmpTopLeftCorner = new Rect();
@@ -110,13 +111,15 @@
private InputMonitor mInputMonitor;
private InputEventReceiver mInputEventReceiver;
private PipTaskOrganizer mPipTaskOrganizer;
+ private PipUiEventLogger mPipUiEventLogger;
private int mCtrlType;
public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig,
PipTaskOrganizer pipTaskOrganizer, Function<Rect, Rect> movementBoundsSupplier,
- Runnable updateMovementBoundsRunnable, SysUiState sysUiState) {
+ Runnable updateMovementBoundsRunnable, SysUiState sysUiState,
+ PipUiEventLogger pipUiEventLogger) {
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = context.getMainExecutor();
@@ -126,6 +129,7 @@
mMovementBoundsSupplier = movementBoundsSupplier;
mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
mSysUiState = sysUiState;
+ mPipUiEventLogger = pipUiEventLogger;
context.getDisplay().getRealSize(mMaxSize);
reloadResources();
@@ -182,6 +186,7 @@
void onActivityUnpinned() {
mIsAttached = false;
+ mUserResizeBounds.setEmpty();
updateIsEnabled();
}
@@ -330,6 +335,7 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (!mLastResizeBounds.isEmpty()) {
+ mUserResizeBounds.set(mLastResizeBounds);
mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
(Rect bounds) -> {
new Handler(Looper.getMainLooper()).post(() -> {
@@ -338,6 +344,8 @@
resetState();
});
});
+ mPipUiEventLogger.log(
+ PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
} else {
resetState();
}
@@ -352,6 +360,18 @@
mThresholdCrossed = false;
}
+ void setUserResizeBounds(Rect bounds) {
+ mUserResizeBounds.set(bounds);
+ }
+
+ void invalidateUserResizeBounds() {
+ mUserResizeBounds.setEmpty();
+ }
+
+ Rect getUserResizeBounds() {
+ return mUserResizeBounds;
+ }
+
void updateMaxSize(int maxX, int maxY) {
mMaxSize.set(maxX, maxY);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index a8130a1..0127ff3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -34,7 +34,6 @@
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
-import android.util.Pair;
import android.util.Size;
import android.view.Gravity;
import android.view.IPinnedStackController;
@@ -55,13 +54,13 @@
import androidx.dynamicanimation.animation.SpringForce;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.systemui.R;
import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipAnimationController;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.pip.PipUiEventLogger;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DismissCircleView;
@@ -94,6 +93,8 @@
private final WindowManager mWindowManager;
private final IActivityManager mActivityManager;
private final PipBoundsHandler mPipBoundsHandler;
+ private final PipUiEventLogger mPipUiEventLogger;
+
private PipResizeGestureHandler mPipResizeGestureHandler;
private IPinnedStackController mPinnedStackController;
@@ -132,9 +133,6 @@
// The current movement bounds
private Rect mMovementBounds = new Rect();
- // The current resized bounds, changed by user resize.
- // This is used during expand/un-expand to save/restore the user's resized size.
- @VisibleForTesting Rect mResizedBounds = new Rect();
// The reference inset bounds, used to determine the dismiss fraction
private Rect mInsetBounds = new Rect();
@@ -198,11 +196,7 @@
@Override
public void onPipDismiss() {
- Pair<ComponentName, Integer> topPipActivity = PipUtils.getTopPipActivity(mContext,
- mActivityManager);
- if (topPipActivity.first != null) {
- MetricsLoggerWrapper.logPictureInPictureDismissByTap(mContext, topPipActivity);
- }
+ mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_TAP_TO_REMOVE);
mTouchState.removeDoubleTapTimeoutCallback();
mMotionHelper.dismissPip();
}
@@ -223,7 +217,8 @@
FloatingContentCoordinator floatingContentCoordinator,
DeviceConfigProxy deviceConfig,
PipSnapAlgorithm pipSnapAlgorithm,
- SysUiState sysUiState) {
+ SysUiState sysUiState,
+ PipUiEventLogger pipUiEventLogger) {
// Initialize the Pip input consumer
mContext = context;
mActivityManager = activityManager;
@@ -238,7 +233,7 @@
mPipResizeGestureHandler =
new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
deviceConfig, pipTaskOrganizer, this::getMovementBounds,
- this::updateMovementBounds, sysUiState);
+ this::updateMovementBounds, sysUiState, pipUiEventLogger);
mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
() -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()),
@@ -259,6 +254,8 @@
pipTaskOrganizer, pipSnapAlgorithm, this::onAccessibilityShowMenu,
this::updateMovementBounds, mHandler);
+ mPipUiEventLogger = pipUiEventLogger;
+
mTargetView = new DismissCircleView(context);
mTargetViewContainer = new FrameLayout(context);
mTargetViewContainer.setBackgroundDrawable(
@@ -303,11 +300,8 @@
hideDismissTarget();
});
- Pair<ComponentName, Integer> topPipActivity = PipUtils.getTopPipActivity(mContext,
- mActivityManager);
- if (topPipActivity.first != null) {
- MetricsLoggerWrapper.logPictureInPictureDismissByDrag(mContext, topPipActivity);
- }
+ mPipUiEventLogger.log(
+ PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_DRAG_TO_REMOVE);
}
});
@@ -379,7 +373,6 @@
mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
}
- mResizedBounds.setEmpty();
mPipResizeGestureHandler.onActivityUnpinned();
}
@@ -389,9 +382,8 @@
mMotionHelper.synchronizePinnedStackBounds();
updateMovementBounds();
if (direction == TRANSITION_DIRECTION_TO_PIP) {
- // updates mResizedBounds only if it's an entering PiP animation
- // mResized should be otherwise updated in setMenuState.
- mResizedBounds.set(mMotionHelper.getBounds());
+ // Set the initial bounds as the user resize bounds.
+ mPipResizeGestureHandler.setUserResizeBounds(mMotionHelper.getBounds());
}
if (mShowPipMenuOnAnimationEnd) {
@@ -430,8 +422,21 @@
}
}
+ /**
+ * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
+ */
+ public void onAspectRatioChanged() {
+ mPipResizeGestureHandler.invalidateUserResizeBounds();
+ }
+
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
+ // Set the user resized bounds equal to the new normal bounds in case they were
+ // invalidated (e.g. by an aspect ratio change).
+ if (mPipResizeGestureHandler.getUserResizeBounds().isEmpty()) {
+ mPipResizeGestureHandler.setUserResizeBounds(normalBounds);
+ }
+
final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
final boolean fromDisplayRotationChanged = (mDisplayRotation != displayRotation);
if (fromDisplayRotationChanged) {
@@ -804,9 +809,7 @@
// Save the current snap fraction and if we do not drag or move the PiP, then
// we store back to this snap fraction. Otherwise, we'll reset the snap
// fraction and snap to the closest edge.
- // Also save the current resized bounds so when the menu disappears, we can restore it.
if (resize) {
- mResizedBounds.set(mMotionHelper.getBounds());
Rect expandedBounds = new Rect(mExpandedBounds);
mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
mMovementBounds, mExpandedMovementBounds, callback);
@@ -835,7 +838,7 @@
}
if (mDeferResizeToNormalBoundsUntilRotation == -1) {
- Rect restoreBounds = new Rect(mResizedBounds);
+ Rect restoreBounds = new Rect(getUserResizeBounds());
Rect restoredMovementBounds = new Rect();
mSnapAlgorithm.getMovementBounds(restoreBounds, mInsetBounds,
restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
@@ -852,8 +855,10 @@
// If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip
// as well, or it can't handle a11y focus and pip menu can't perform any action.
onRegistrationChanged(menuState == MENU_STATE_NONE);
- if (menuState != MENU_STATE_CLOSE) {
- MetricsLoggerWrapper.logPictureInPictureMenuVisible(mContext, menuState == MENU_STATE_FULL);
+ if (menuState == MENU_STATE_NONE) {
+ mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_HIDE_MENU);
+ } else if (menuState == MENU_STATE_FULL) {
+ mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_SHOW_MENU);
}
}
@@ -886,6 +891,10 @@
return mNormalBounds;
}
+ Rect getUserResizeBounds() {
+ return mPipResizeGestureHandler.getUserResizeBounds();
+ }
+
/**
* Gesture controlling normal movement of the PIP.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index 8001ecc..59118bf 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -45,27 +45,33 @@
@Singleton
class PrivacyItemController @Inject constructor(
- context: Context,
private val appOpsController: AppOpsController,
@Main uiExecutor: DelayableExecutor,
@Background private val bgExecutor: Executor,
private val broadcastDispatcher: BroadcastDispatcher,
private val deviceConfigProxy: DeviceConfigProxy,
+ private val userManager: UserManager,
dumpManager: DumpManager
) : Dumpable {
@VisibleForTesting
internal companion object {
- val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_RECORD_AUDIO,
+ val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE)
+ val OPS_LOCATION = intArrayOf(
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION)
+ val OPS = OPS_MIC_CAMERA + OPS_LOCATION
val intentFilter = IntentFilter().apply {
addAction(Intent.ACTION_USER_SWITCHED)
addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
}
const val TAG = "PrivacyItemController"
+ private const val ALL_INDICATORS =
+ SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED
+ private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED
}
@VisibleForTesting
@@ -73,12 +79,16 @@
@Synchronized get() = field.toList() // Returns a shallow copy of the list
@Synchronized set
- fun isPermissionsHubEnabled(): Boolean {
+ fun isAllIndicatorsEnabled(): Boolean {
return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
+ ALL_INDICATORS, false)
}
- private val userManager = context.getSystemService(UserManager::class.java)
+ private fun isMicCameraEnabled(): Boolean {
+ return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+ MIC_CAMERA, false)
+ }
+
private var currentUserIds = emptyList<Int>()
private var listening = false
private val callbacks = mutableListOf<WeakReference<Callback>>()
@@ -86,7 +96,7 @@
private val notifyChanges = Runnable {
val list = privacyList
- callbacks.forEach { it.get()?.privacyChanged(list) }
+ callbacks.forEach { it.get()?.onPrivacyItemsChanged(list) }
}
private val updateListAndNotifyChanges = Runnable {
@@ -94,20 +104,32 @@
uiExecutor.execute(notifyChanges)
}
- private var indicatorsAvailable = isPermissionsHubEnabled()
- @VisibleForTesting
- internal val devicePropertiesChangedListener =
+ var allIndicatorsAvailable = isAllIndicatorsEnabled()
+ private set
+ var micCameraAvailable = isMicCameraEnabled()
+ private set
+
+ private val devicePropertiesChangedListener =
object : DeviceConfig.OnPropertiesChangedListener {
override fun onPropertiesChanged(properties: DeviceConfig.Properties) {
- if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace()) &&
- properties.getKeyset().contains(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) {
- indicatorsAvailable = properties.getBoolean(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
- internalUiExecutor.updateListeningState()
+ if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace()) &&
+ (properties.keyset.contains(ALL_INDICATORS) ||
+ properties.keyset.contains(MIC_CAMERA))) {
+
+ // Running on the ui executor so can iterate on callbacks
+ if (properties.keyset.contains(ALL_INDICATORS)) {
+ allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, false)
+ callbacks.forEach { it.get()?.onFlagAllChanged(allIndicatorsAvailable) }
+ }
+
+ if (properties.keyset.contains(MIC_CAMERA)) {
+ micCameraAvailable = properties.getBoolean(MIC_CAMERA, false)
+ callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) }
+ }
+ internalUiExecutor.updateListeningState()
+ }
}
}
- }
private val cb = object : AppOpsController.Callback {
override fun onActiveStateChanged(
@@ -116,6 +138,10 @@
packageName: String,
active: Boolean
) {
+ // Check if we care about this code right now
+ if (!allIndicatorsAvailable && code in OPS_LOCATION) {
+ return
+ }
val userId = UserHandle.getUserId(uid)
if (userId in currentUserIds) {
update(false)
@@ -159,13 +185,16 @@
}
/**
- * Updates listening status based on whether there are callbacks and the indicators are enabled
+ * Updates listening status based on whether there are callbacks and the indicators are enabled.
+ *
+ * Always listen to all OPS so we don't have to figure out what we should be listening to. We
+ * still have to filter anyway. Updates are filtered in the callback.
*
* This is only called from private (add/remove)Callback and from the config listener, all in
* main thread.
*/
private fun setListeningState() {
- val listen = !callbacks.isEmpty() and indicatorsAvailable
+ val listen = !callbacks.isEmpty() and (allIndicatorsAvailable || micCameraAvailable)
if (listening == listen) return
listening = listen
if (listening) {
@@ -220,19 +249,28 @@
private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
val type: PrivacyType = when (appOpItem.code) {
+ AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
- AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
else -> return null
}
+ if (type == PrivacyType.TYPE_LOCATION && !allIndicatorsAvailable) return null
val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid)
return PrivacyItem(type, app)
}
// Used by containing class to get notified of changes
interface Callback {
- fun privacyChanged(privacyItems: List<PrivacyItem>)
+ fun onPrivacyItemsChanged(privacyItems: List<PrivacyItem>)
+
+ @JvmDefault
+ fun onFlagAllChanged(flag: Boolean) {}
+
+ @JvmDefault
+ fun onFlagMicCameraChanged(flag: Boolean) {}
}
internal inner class Receiver : BroadcastReceiver() {
@@ -248,7 +286,7 @@
private val list: List<PrivacyItem>
) : Runnable {
override fun run() {
- callback?.privacyChanged(list)
+ callback?.onPrivacyItemsChanged(list)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index a559a54..58c723c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -33,7 +33,6 @@
import android.os.Handler;
import android.os.Looper;
import android.provider.AlarmClock;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
@@ -59,7 +58,6 @@
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
@@ -154,7 +152,8 @@
private Space mSpace;
private BatteryMeterView mBatteryRemainingIcon;
private RingerModeTracker mRingerModeTracker;
- private boolean mPermissionsHubEnabled;
+ private boolean mAllIndicatorsEnabled;
+ private boolean mMicCameraIndicatorsEnabled;
private PrivacyItemController mPrivacyItemController;
private final UiEventLogger mUiEventLogger;
@@ -173,27 +172,34 @@
private float mKeyguardExpansionFraction;
private boolean mPrivacyChipLogged = false;
- private final DeviceConfig.OnPropertiesChangedListener mPropertiesListener =
- new DeviceConfig.OnPropertiesChangedListener() {
- @Override
- public void onPropertiesChanged(DeviceConfig.Properties properties) {
- if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace())
- && properties.getKeyset()
- .contains(SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) {
- mPermissionsHubEnabled = properties.getBoolean(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false);
- StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
- iconContainer.setIgnoredSlots(getIgnoredIconSlots());
- }
- }
- };
-
private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
@Override
- public void privacyChanged(List<PrivacyItem> privacyItems) {
+ public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) {
mPrivacyChip.setPrivacyList(privacyItems);
setChipVisibility(!privacyItems.isEmpty());
}
+
+ @Override
+ public void onFlagAllChanged(boolean flag) {
+ if (mAllIndicatorsEnabled != flag) {
+ mAllIndicatorsEnabled = flag;
+ update();
+ }
+ }
+
+ @Override
+ public void onFlagMicCameraChanged(boolean flag) {
+ if (mMicCameraIndicatorsEnabled != flag) {
+ mMicCameraIndicatorsEnabled = flag;
+ update();
+ }
+ }
+
+ private void update() {
+ StatusIconContainer iconContainer = requireViewById(R.id.statusIcons);
+ iconContainer.setIgnoredSlots(getIgnoredIconSlots());
+ setChipVisibility(!mPrivacyChip.getPrivacyList().isEmpty());
+ }
};
@Inject
@@ -276,7 +282,8 @@
mRingerModeTextView.setSelected(true);
mNextAlarmTextView.setSelected(true);
- mPermissionsHubEnabled = mPrivacyItemController.isPermissionsHubEnabled();
+ mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
+ mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
}
public QuickQSPanel getHeaderQsPanel() {
@@ -285,13 +292,15 @@
private List<String> getIgnoredIconSlots() {
ArrayList<String> ignored = new ArrayList<>();
- ignored.add(mContext.getResources().getString(
- com.android.internal.R.string.status_bar_camera));
- ignored.add(mContext.getResources().getString(
- com.android.internal.R.string.status_bar_microphone));
- if (mPermissionsHubEnabled) {
+ if (getChipEnabled()) {
ignored.add(mContext.getResources().getString(
- com.android.internal.R.string.status_bar_location));
+ com.android.internal.R.string.status_bar_camera));
+ ignored.add(mContext.getResources().getString(
+ com.android.internal.R.string.status_bar_microphone));
+ if (mAllIndicatorsEnabled) {
+ ignored.add(mContext.getResources().getString(
+ com.android.internal.R.string.status_bar_location));
+ }
}
return ignored;
@@ -309,7 +318,7 @@
}
private void setChipVisibility(boolean chipVisible) {
- if (chipVisible && mPermissionsHubEnabled) {
+ if (chipVisible && getChipEnabled()) {
mPrivacyChip.setVisibility(View.VISIBLE);
// Makes sure that the chip is logged as viewed at most once each time QS is opened
// mListening makes sure that the callback didn't return after the user closed QS
@@ -519,9 +528,6 @@
});
mStatusBarIconController.addIconGroup(mIconManager);
requestApplyInsets();
- // Change the ignored slots when DeviceConfig flag changes
- DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
- mContext.getMainExecutor(), mPropertiesListener);
}
@Override
@@ -601,7 +607,6 @@
setListening(false);
mRingerModeTracker.getRingerModeInternal().removeObservers(this);
mStatusBarIconController.removeIconGroup(mIconManager);
- DeviceConfig.removeOnPropertiesChangedListener(mPropertiesListener);
super.onDetachedFromWindow();
}
@@ -619,6 +624,9 @@
mZenController.addCallback(this);
mAlarmController.addCallback(this);
mLifecycle.setCurrentState(Lifecycle.State.RESUMED);
+ // Get the most up to date info
+ mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
+ mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
mPrivacyItemController.addCallback(mPICCallback);
} else {
mZenController.removeCallback(this);
@@ -760,4 +768,8 @@
updateHeaderTextContainerAlphaAnimator();
}
}
+
+ private boolean getChipEnabled() {
+ return mMicCameraIndicatorsEnabled || mAllIndicatorsEnabled;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index f249504..7150e43 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -111,6 +111,7 @@
: mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.icon = mIcon;
state.label = mContext.getString(R.string.battery_detail_switch_title);
+ state.secondaryLabel = "";
state.contentDescription = state.label;
state.value = mPowerSave;
state.expandedAccessibilityClassName = Switch.class.getName();
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 476ec79..acc7f81 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -21,7 +21,6 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -69,7 +68,6 @@
private static final String ACTION_STOP_NOTIF =
"com.android.systemui.screenrecord.STOP_FROM_NOTIF";
private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE";
- private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE";
private final RecordingController mController;
@@ -181,23 +179,6 @@
startActivity(Intent.createChooser(shareIntent, shareLabel)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
break;
- case ACTION_DELETE:
- // Close quick shade
- sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
-
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH));
- resolver.delete(uri, null, null);
-
- Toast.makeText(
- this,
- R.string.screenrecord_delete_description,
- Toast.LENGTH_LONG).show();
-
- // Remove notification
- mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
- Log.d(TAG, "Deleted recording " + uri);
- break;
}
return Service.START_STICKY;
}
@@ -307,16 +288,6 @@
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
.build();
- Notification.Action deleteAction = new Notification.Action.Builder(
- Icon.createWithResource(this, R.drawable.ic_screenrecord),
- getResources().getString(R.string.screenrecord_delete_label),
- PendingIntent.getService(
- this,
- REQUEST_CODE,
- getDeleteIntent(this, uri.toString()),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
- .build();
-
Bundle extras = new Bundle();
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
getResources().getString(R.string.screenrecord_name));
@@ -330,7 +301,6 @@
viewIntent,
PendingIntent.FLAG_IMMUTABLE))
.addAction(shareAction)
- .addAction(deleteAction)
.setAutoCancel(true)
.addExtras(extras);
@@ -409,11 +379,6 @@
.putExtra(EXTRA_PATH, path);
}
- private static Intent getDeleteIntent(Context context, String path) {
- return new Intent(context, RecordingService.class).setAction(ACTION_DELETE)
- .putExtra(EXTRA_PATH, path);
- }
-
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Log.d(TAG, "Media recorder info: " + what);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c535230..853897f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -565,7 +565,12 @@
private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,
Insets screenInsets, boolean showFlash) {
- dismissScreenshot("new screenshot requested", true);
+ if (mScreenshotLayout.isAttachedToWindow()) {
+ if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED);
+ }
+ dismissScreenshot("new screenshot requested", true);
+ }
mScreenBitmap = screenshot;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
index b5209bb..a488702 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
@@ -65,10 +65,10 @@
}
void setIcon(Icon icon, boolean tint) {
- if (tint) {
- icon.setTint(mIconColor);
- }
mIcon.setImageIcon(icon);
+ if (!tint) {
+ mIcon.setImageTintList(null);
+ }
}
void setText(CharSequence text) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
index 20fa991..8535d57 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
@@ -56,7 +56,9 @@
@UiEvent(doc = "screenshot interaction timed out")
SCREENSHOT_INTERACTION_TIMEOUT(310),
@UiEvent(doc = "screenshot explicitly dismissed")
- SCREENSHOT_EXPLICIT_DISMISSAL(311);
+ SCREENSHOT_EXPLICIT_DISMISSAL(311),
+ @UiEvent(doc = "screenshot reentered for new screenshot")
+ SCREENSHOT_REENTERED(640);
private final int mId;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt
new file mode 100644
index 0000000..9d05843
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.settings
+
+import android.content.ContentResolver
+
+interface CurrentUserContentResolverProvider {
+
+ val currentUserContentResolver: ContentResolver
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
index 825a7f3..d7c4caaa 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
@@ -16,6 +16,7 @@
package com.android.systemui.settings
+import android.content.ContentResolver
import android.content.Context
import android.os.UserHandle
import androidx.annotation.VisibleForTesting
@@ -31,7 +32,7 @@
class CurrentUserContextTracker internal constructor(
private val sysuiContext: Context,
broadcastDispatcher: BroadcastDispatcher
-) {
+) : CurrentUserContentResolverProvider {
private val userTracker: CurrentUserTracker
private var initialized = false
@@ -44,6 +45,9 @@
return _curUserContext!!
}
+ override val currentUserContentResolver: ContentResolver
+ get() = currentUserContext.contentResolver
+
init {
userTracker = object : CurrentUserTracker(broadcastDispatcher) {
override fun onUserSwitched(newUserId: Int) {
@@ -54,8 +58,8 @@
fun initialize() {
initialized = true
- _curUserContext = makeUserContext(userTracker.currentUserId)
userTracker.startTracking()
+ _curUserContext = makeUserContext(userTracker.currentUserId)
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
index 2c5c3ce..eb5bd5c 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
@@ -19,10 +19,12 @@
import android.content.Context;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.settings.CurrentUserContentResolverProvider;
import com.android.systemui.settings.CurrentUserContextTracker;
import javax.inject.Singleton;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -30,7 +32,7 @@
* Dagger Module for classes found within the com.android.systemui.settings package.
*/
@Module
-public interface SettingsModule {
+public abstract class SettingsModule {
/**
* Provides and initializes a CurrentUserContextTracker
@@ -45,4 +47,9 @@
tracker.initialize();
return tracker;
}
+
+ @Binds
+ @Singleton
+ abstract CurrentUserContentResolverProvider bindCurrentUserContentResolverTracker(
+ CurrentUserContextTracker tracker);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index a144453..7e1dc66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -140,7 +140,7 @@
* Creates a new KeyguardIndicationController and registers callbacks.
*/
@Inject
- KeyguardIndicationController(Context context,
+ public KeyguardIndicationController(Context context,
WakeLock.Builder wakeLockBuilder,
KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController,
@@ -523,8 +523,7 @@
});
}
- @VisibleForTesting
- String computePowerIndication() {
+ protected String computePowerIndication() {
if (mPowerCharged) {
return mContext.getResources().getString(R.string.keyguard_charged);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 5bee9a7..6b8afff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -486,7 +486,6 @@
}
}
- row.showAppOpsIcons(entry.mActiveAppOps);
row.setLastAudiblyAlertedMs(entry.getLastAudiblyAlertedMs());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
index 4b244bb..84108b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
@@ -76,14 +76,9 @@
// extend the lifetime of foreground notification services to show for at least 5 seconds
mNotifPipeline.addNotificationLifetimeExtender(mForegroundLifetimeExtender);
- // listen for new notifications to add appOps
- mNotifPipeline.addCollectionListener(mNotifCollectionListener);
-
// filter out foreground service notifications that aren't necessary anymore
mNotifPipeline.addPreGroupFilter(mNotifFilter);
- // when appOps change, update any relevant notifications to update appOps for
- mAppOpsController.addCallback(ForegroundServiceController.APP_OPS, this::onAppOpsChanged);
}
/**
@@ -174,82 +169,4 @@
}
}
};
-
- /**
- * Adds appOps to incoming and updating notifications
- */
- private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
- @Override
- public void onEntryAdded(NotificationEntry entry) {
- tagAppOps(entry);
- }
-
- @Override
- public void onEntryUpdated(NotificationEntry entry) {
- tagAppOps(entry);
- }
-
- private void tagAppOps(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- // note: requires that the ForegroundServiceController is updating their appOps first
- ArraySet<Integer> activeOps =
- mForegroundServiceController.getAppOps(
- sbn.getUser().getIdentifier(),
- sbn.getPackageName());
-
- entry.mActiveAppOps.clear();
- if (activeOps != null) {
- entry.mActiveAppOps.addAll(activeOps);
- }
- }
- };
-
- private void onAppOpsChanged(int code, int uid, String packageName, boolean active) {
- mMainExecutor.execute(() -> handleAppOpsChanged(code, uid, packageName, active));
- }
-
- /**
- * Update the appOp for the posted notification associated with the current foreground service
- *
- * @param code code for appOp to add/remove
- * @param uid of user the notification is sent to
- * @param packageName package that created the notification
- * @param active whether the appOpCode is active or not
- */
- private void handleAppOpsChanged(int code, int uid, String packageName, boolean active) {
- Assert.isMainThread();
-
- int userId = UserHandle.getUserId(uid);
-
- // Update appOps of the app's posted notifications with standard layouts
- final ArraySet<String> notifKeys =
- mForegroundServiceController.getStandardLayoutKeys(userId, packageName);
- if (notifKeys != null) {
- boolean changed = false;
- for (int i = 0; i < notifKeys.size(); i++) {
- final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i));
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- if (active) {
- changed |= entry.mActiveAppOps.add(code);
- } else {
- changed |= entry.mActiveAppOps.remove(code);
- }
- }
- }
- if (changed) {
- mNotifFilter.invalidateList();
- }
- }
- }
-
- private NotificationEntry findNotificationEntryWithKey(String key) {
- for (NotificationEntry entry : mNotifPipeline.getAllNotifs()) {
- if (entry.getKey().equals(key)) {
- return entry;
- }
- }
- return null;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
deleted file mode 100644
index 28c53dc..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.notification.row;
-
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
-import android.util.ArraySet;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-
-/**
- * The guts of a notification revealed when performing a long press.
- */
-public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsContent {
- private static final String TAG = "AppOpsGuts";
-
- private PackageManager mPm;
-
- private String mPkg;
- private String mAppName;
- private int mAppUid;
- private StatusBarNotification mSbn;
- private ArraySet<Integer> mAppOps;
- private MetricsLogger mMetricsLogger;
- private OnSettingsClickListener mOnSettingsClickListener;
- private NotificationGuts mGutsContainer;
- private UiEventLogger mUiEventLogger;
-
- private OnClickListener mOnOk = v -> {
- mGutsContainer.closeControls(v, false);
- };
-
- public AppOpsInfo(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public interface OnSettingsClickListener {
- void onClick(View v, String pkg, int uid, ArraySet<Integer> ops);
- }
-
- public void bindGuts(final PackageManager pm,
- final OnSettingsClickListener onSettingsClick,
- final StatusBarNotification sbn,
- final UiEventLogger uiEventLogger,
- ArraySet<Integer> activeOps) {
- mPkg = sbn.getPackageName();
- mSbn = sbn;
- mPm = pm;
- mAppName = mPkg;
- mOnSettingsClickListener = onSettingsClick;
- mAppOps = activeOps;
- mUiEventLogger = uiEventLogger;
-
- bindHeader();
- bindPrompt();
- bindButtons();
-
- logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN);
- mMetricsLogger = new MetricsLogger();
- mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true);
- }
-
- private void bindHeader() {
- // Package name
- Drawable pkgicon = null;
- ApplicationInfo info;
- try {
- info = mPm.getApplicationInfo(mPkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (info != null) {
- mAppUid = mSbn.getUid();
- mAppName = String.valueOf(mPm.getApplicationLabel(info));
- pkgicon = mPm.getApplicationIcon(info);
- }
- } catch (PackageManager.NameNotFoundException e) {
- // app is gone, just show package name and generic icon
- pkgicon = mPm.getDefaultActivityIcon();
- }
- ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
- ((TextView) findViewById(R.id.pkgname)).setText(mAppName);
- }
-
- private void bindPrompt() {
- final TextView prompt = findViewById(R.id.prompt);
- prompt.setText(getPrompt());
- }
-
- private void bindButtons() {
- View settings = findViewById(R.id.settings);
- settings.setOnClickListener((View view) -> {
- mOnSettingsClickListener.onClick(view, mPkg, mAppUid, mAppOps);
- });
- TextView ok = findViewById(R.id.ok);
- ok.setOnClickListener(mOnOk);
- ok.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate());
- }
-
- private String getPrompt() {
- if (mAppOps == null || mAppOps.size() == 0) {
- return "";
- } else if (mAppOps.size() == 1) {
- if (mAppOps.contains(AppOpsManager.OP_CAMERA)) {
- return mContext.getString(R.string.appops_camera);
- } else if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) {
- return mContext.getString(R.string.appops_microphone);
- } else {
- return mContext.getString(R.string.appops_overlay);
- }
- } else if (mAppOps.size() == 2) {
- if (mAppOps.contains(AppOpsManager.OP_CAMERA)) {
- if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) {
- return mContext.getString(R.string.appops_camera_mic);
- } else {
- return mContext.getString(R.string.appops_camera_overlay);
- }
- } else {
- return mContext.getString(R.string.appops_mic_overlay);
- }
- } else {
- return mContext.getString(R.string.appops_camera_mic_overlay);
- }
- }
-
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- if (mGutsContainer != null &&
- event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- if (mGutsContainer.isExposed()) {
- event.getText().add(mContext.getString(
- R.string.notification_channel_controls_opened_accessibility, mAppName));
- } else {
- event.getText().add(mContext.getString(
- R.string.notification_channel_controls_closed_accessibility, mAppName));
- }
- }
- }
-
- @Override
- public void setGutsParent(NotificationGuts guts) {
- mGutsContainer = guts;
- }
-
- @Override
- public boolean willBeRemoved() {
- return false;
- }
-
- @Override
- public boolean shouldBeSaved() {
- return false;
- }
-
- @Override
- public boolean needsFalsingProtection() {
- return false;
- }
-
- @Override
- public View getContentView() {
- return this;
- }
-
- @Override
- public boolean handleCloseControls(boolean save, boolean force) {
- logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_CLOSE);
- if (mMetricsLogger != null) {
- mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false);
- }
- return false;
- }
-
- @Override
- public int getActualHeight() {
- return getHeight();
- }
-
- private void logUiEvent(NotificationAppOpsEvent event) {
- if (mSbn != null) {
- mUiEventLogger.logWithInstanceId(event,
- mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 94e12e8..8ead7bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -239,7 +239,6 @@
private boolean mShowNoBackground;
private ExpandableNotificationRow mNotificationParent;
private OnExpandClickListener mOnExpandClickListener;
- private View.OnClickListener mOnAppOpsClickListener;
// Listener will be called when receiving a long click event.
// Use #setLongPressPosition to optionally assign positional data with the long press.
@@ -1143,7 +1142,6 @@
items.add(NotificationMenuRow.createPartialConversationItem(mContext));
items.add(NotificationMenuRow.createInfoItem(mContext));
items.add(NotificationMenuRow.createSnoozeItem(mContext));
- items.add(NotificationMenuRow.createAppOpsItem(mContext));
mMenuRow.setMenuItems(items);
}
if (existed) {
@@ -1609,7 +1607,6 @@
RowContentBindStage rowContentBindStage,
OnExpandClickListener onExpandClickListener,
NotificationMediaManager notificationMediaManager,
- OnAppOpsClickListener onAppOpsClickListener,
FalsingManager falsingManager,
StatusBarStateController statusBarStateController,
PeopleNotificationIdentifier peopleNotificationIdentifier) {
@@ -1629,7 +1626,6 @@
mRowContentBindStage = rowContentBindStage;
mOnExpandClickListener = onExpandClickListener;
mMediaManager = notificationMediaManager;
- setAppOpsOnClickListener(onAppOpsClickListener);
mFalsingManager = falsingManager;
mStatusbarStateController = statusBarStateController;
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
@@ -1686,14 +1682,6 @@
requestLayout();
}
- public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mIsSummaryWithChildren) {
- mChildrenContainer.showAppOpsIcons(activeOps);
- }
- mPrivateLayout.showAppOpsIcons(activeOps);
- mPublicLayout.showAppOpsIcons(activeOps);
- }
-
/** Sets the last time the notification being displayed audibly alerted the user. */
public void setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) {
if (NotificationUtils.useNewInterruptionModel(mContext)) {
@@ -1722,24 +1710,6 @@
mPublicLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
- public View.OnClickListener getAppOpsOnClickListener() {
- return mOnAppOpsClickListener;
- }
-
- void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) {
- mOnAppOpsClickListener = v -> {
- createMenu();
- NotificationMenuRowPlugin provider = getProvider();
- if (provider == null) {
- return;
- }
- MenuItem menuItem = provider.getAppOpsMenuItem(mContext);
- if (menuItem != null) {
- l.onClick(this, v.getWidth() / 2, v.getHeight() / 2, menuItem);
- }
- };
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 7a6109d..b132caf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -63,7 +63,6 @@
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
this::logNotificationExpansion;
- private final ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
private final NotificationGutsManager mNotificationGutsManager;
private Runnable mOnDismissRunnable;
private final FalsingManager mFalsingManager;
@@ -101,7 +100,6 @@
mStatusBarStateController = statusBarStateController;
mNotificationGutsManager = notificationGutsManager;
mOnDismissRunnable = onDismissRunnable;
- mOnAppOpsClickListener = mNotificationGutsManager::openGuts;
mAllowLongPress = allowLongPress;
mFalsingManager = falsingManager;
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
@@ -122,7 +120,6 @@
mRowContentBindStage,
mOnExpandClickListener,
mMediaManager,
- mOnAppOpsClickListener,
mFalsingManager,
mStatusBarStateController,
mPeopleNotificationIdentifier
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 1f5b063..41a9b18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1567,18 +1567,6 @@
return header;
}
- public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mContractedChild != null) {
- mContractedWrapper.showAppOpsIcons(activeOps);
- }
- if (mExpandedChild != null) {
- mExpandedWrapper.showAppOpsIcons(activeOps);
- }
- if (mHeadsUpChild != null) {
- mHeadsUpWrapper.showAppOpsIcons(activeOps);
- }
- }
-
/** Sets whether the notification being displayed audibly alerted the user. */
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
if (mContractedChild != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 24883f5..3eed18a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -264,8 +264,6 @@
try {
if (gutsView instanceof NotificationSnooze) {
initializeSnoozeView(row, (NotificationSnooze) gutsView);
- } else if (gutsView instanceof AppOpsInfo) {
- initializeAppOpsInfo(row, (AppOpsInfo) gutsView);
} else if (gutsView instanceof NotificationInfo) {
initializeNotificationInfo(row, (NotificationInfo) gutsView);
} else if (gutsView instanceof NotificationConversationInfo) {
@@ -303,36 +301,6 @@
}
/**
- * Sets up the {@link AppOpsInfo} inside the notification row's guts.
- *
- * @param row view to set up the guts for
- * @param appOpsInfoView view to set up/bind within {@code row}
- */
- private void initializeAppOpsInfo(
- final ExpandableNotificationRow row,
- AppOpsInfo appOpsInfoView) {
- NotificationGuts guts = row.getGuts();
- StatusBarNotification sbn = row.getEntry().getSbn();
- UserHandle userHandle = sbn.getUser();
- PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
- userHandle.getIdentifier());
-
- AppOpsInfo.OnSettingsClickListener onSettingsClick =
- (View v, String pkg, int uid, ArraySet<Integer> ops) -> {
- mUiEventLogger.logWithInstanceId(
- NotificationAppOpsEvent.NOTIFICATION_APP_OPS_SETTINGS_CLICK,
- sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId());
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
- guts.resetFalsingCheck();
- startAppOpsSettingsActivity(pkg, uid, ops, row);
- };
- if (!row.getEntry().mActiveAppOps.isEmpty()) {
- appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, mUiEventLogger,
- row.getEntry().mActiveAppOps);
- }
- }
-
- /**
* Sets up the {@link NotificationInfo} inside the notification row's guts.
* @param row view to set up the guts for
* @param notificationInfoView view to set up/bind within {@code row}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 5e1e3b2..a167925 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -76,7 +76,6 @@
private Context mContext;
private FrameLayout mMenuContainer;
private NotificationMenuItem mInfoItem;
- private MenuItem mAppOpsItem;
private MenuItem mSnoozeItem;
private ArrayList<MenuItem> mLeftMenuItems;
private ArrayList<MenuItem> mRightMenuItems;
@@ -138,11 +137,6 @@
}
@Override
- public MenuItem getAppOpsMenuItem(Context context) {
- return mAppOpsItem;
- }
-
- @Override
public MenuItem getSnoozeMenuItem(Context context) {
return mSnoozeItem;
}
@@ -264,7 +258,6 @@
// Only show snooze for non-foreground notifications, and if the setting is on
mSnoozeItem = createSnoozeItem(mContext);
}
- mAppOpsItem = createAppOpsItem(mContext);
NotificationEntry entry = mParent.getEntry();
int personNotifType = mPeopleNotificationIdentifier
.getPeopleNotificationType(entry.getSbn(), entry.getRanking());
@@ -280,7 +273,6 @@
mRightMenuItems.add(mSnoozeItem);
}
mRightMenuItems.add(mInfoItem);
- mRightMenuItems.add(mAppOpsItem);
mLeftMenuItems.addAll(mRightMenuItems);
populateMenuViews();
@@ -688,14 +680,6 @@
R.drawable.ic_settings);
}
- static MenuItem createAppOpsItem(Context context) {
- AppOpsInfo appOpsContent = (AppOpsInfo) LayoutInflater.from(context).inflate(
- R.layout.app_ops_info, null, false);
- MenuItem info = new NotificationMenuItem(context, null, appOpsContent,
- -1 /*don't show in slow swipe menu */);
- return info;
- }
-
private void addMenuView(MenuItem item, ViewGroup parent) {
View menuView = item.getMenuView();
if (menuView != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index c747a7c..86fc352 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -18,7 +18,6 @@
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
-import android.app.AppOpsManager;
import android.app.Notification;
import android.content.Context;
import android.util.ArraySet;
@@ -64,10 +63,6 @@
private TextView mHeaderText;
private TextView mAppNameText;
private ImageView mWorkProfileImage;
- private View mCameraIcon;
- private View mMicIcon;
- private View mOverlayIcon;
- private View mAppOps;
private View mAudiblyAlertedIcon;
private FrameLayout mIconContainer;
@@ -108,7 +103,6 @@
}
}, TRANSFORMING_VIEW_TITLE);
resolveHeaderViews();
- addAppOpsOnClickListener(row);
}
protected void resolveHeaderViews() {
@@ -119,10 +113,6 @@
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
- mCameraIcon = mView.findViewById(com.android.internal.R.id.camera);
- mMicIcon = mView.findViewById(com.android.internal.R.id.mic);
- mOverlayIcon = mView.findViewById(com.android.internal.R.id.overlay);
- mAppOps = mView.findViewById(com.android.internal.R.id.app_ops);
mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon);
if (mNotificationHeader != null) {
mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
@@ -130,38 +120,6 @@
}
}
- private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
- View.OnClickListener listener = row.getAppOpsOnClickListener();
- if (mNotificationHeader != null) {
- mNotificationHeader.setAppOpsOnClickListener(listener);
- }
- if (mAppOps != null) {
- mAppOps.setOnClickListener(listener);
- }
- }
-
- /**
- * Shows or hides 'app op in use' icons based on app usage.
- */
- @Override
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- if (appOps == null) {
- return;
- }
- if (mOverlayIcon != null) {
- mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
- ? View.VISIBLE : View.GONE);
- }
- if (mCameraIcon != null) {
- mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
- ? View.VISIBLE : View.GONE);
- }
- if (mMicIcon != null) {
- mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
- ? View.VISIBLE : View.GONE);
- }
- }
-
@Override
public void onContentUpdated(ExpandableNotificationRow row) {
super.onContentUpdated(row);
@@ -285,15 +243,6 @@
mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
mHeaderText);
}
- if (mCameraIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mCameraIcon);
- }
- if (mMicIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mMicIcon);
- }
- if (mOverlayIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mOverlayIcon);
- }
if (mAudiblyAlertedIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mAudiblyAlertedIcon);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 30080e3..4bf2794 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -96,14 +96,6 @@
public void onContentUpdated(ExpandableNotificationRow row) {
}
- /**
- * Show a set of app opp icons in the layout.
- *
- * @param appOps which app ops to show
- */
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- }
-
public void onReinflated() {
if (shouldClearBackgroundOnReapply()) {
mBackgroundColor = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 99691b7..5edcde1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -1302,20 +1302,6 @@
mCurrentHeaderTranslation = (int) ((1.0f - headerVisibleAmount) * mTranslationForHeader);
}
- /**
- * Show a set of app opp icons in the layout.
- *
- * @param appOps which app ops to show
- */
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- if (mNotificationHeaderWrapper != null) {
- mNotificationHeaderWrapper.showAppOpsIcons(appOps);
- }
- if (mNotificationHeaderWrapperLowPriority != null) {
- mNotificationHeaderWrapperLowPriority.showAppOpsIcons(appOps);
- }
- }
-
public void setRecentlyAudiblyAlerted(boolean audiblyAlertedRecently) {
if (mNotificationHeaderWrapper != null) {
mNotificationHeaderWrapper.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index 16b5a23..78742f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -33,6 +33,8 @@
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import com.android.systemui.statusbar.policy.KeyButtonView;
+import java.util.function.Consumer;
+
/** Containing logic for the rotation button on the physical left bottom corner of the screen. */
public class FloatingRotationButton implements RotationButton {
@@ -48,6 +50,7 @@
private boolean mCanShow = true;
private RotationButtonController mRotationButtonController;
+ private Consumer<Boolean> mVisibilityChangedCallback;
FloatingRotationButton(Context context) {
mContext = context;
@@ -68,6 +71,11 @@
}
@Override
+ public void setVisibilityChangedCallback(Consumer<Boolean> visibilityChangedCallback) {
+ mVisibilityChangedCallback = visibilityChangedCallback;
+ }
+
+ @Override
public View getCurrentView() {
return mKeyButtonView;
}
@@ -107,6 +115,16 @@
mKeyButtonDrawable.resetAnimation();
mKeyButtonDrawable.startAnimation();
}
+ mKeyButtonView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5,
+ int i6, int i7) {
+ if (mIsShowing && mVisibilityChangedCallback != null) {
+ mVisibilityChangedCallback.accept(true);
+ }
+ mKeyButtonView.removeOnLayoutChangeListener(this);
+ }
+ });
return true;
}
@@ -117,6 +135,9 @@
}
mWindowManager.removeViewImmediate(mKeyButtonView);
mIsShowing = false;
+ if (mVisibilityChangedCallback != null) {
+ mVisibilityChangedCallback.accept(false);
+ }
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index c99a1de..e60293c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -192,6 +192,7 @@
private int mLayoutDirection;
private boolean mForceNavBarHandleOpaque;
+ private boolean mIsCurrentUserSetup;
/** @see android.view.WindowInsetsController#setSystemBarsAppearance(int) */
private @Appearance int mAppearance;
@@ -311,6 +312,10 @@
@Override
public void onNavBarButtonAlphaChanged(float alpha, boolean animate) {
+ if (!mIsCurrentUserSetup) {
+ // If the current user is not yet setup, then don't update any button alphas
+ return;
+ }
ButtonDispatcher buttonDispatcher = null;
boolean forceVisible = false;
if (QuickStepContract.isSwipeUpMode(mNavBarMode)) {
@@ -349,15 +354,6 @@
}
};
- private final ContextButtonListener mRotationButtonListener = (button, visible) -> {
- if (visible) {
- // If the button will actually become visible and the navbar is about to hide,
- // tell the statusbar to keep it around for longer
- mAutoHideController.touchAutoHide();
- mNavigationBarView.notifyActiveTouchRegions();
- }
- };
-
private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true);
private final ContentObserver mAssistContentObserver = new ContentObserver(
@@ -384,6 +380,14 @@
}
};
+ private final DeviceProvisionedController.DeviceProvisionedListener mUserSetupListener =
+ new DeviceProvisionedController.DeviceProvisionedListener() {
+ @Override
+ public void onUserSetupChanged() {
+ mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+ }
+ };
+
@Inject
public NavigationBarFragment(AccessibilityManagerWrapper accessibilityManagerWrapper,
DeviceProvisionedController deviceProvisionedController, MetricsLogger metricsLogger,
@@ -451,6 +455,9 @@
/* defaultValue = */ true);
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener);
+
+ mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+ mDeviceProvisionedController.addCallback(mUserSetupListener);
}
@Override
@@ -459,6 +466,7 @@
mNavigationModeController.removeListener(this);
mAccessibilityManagerWrapper.removeCallback(mAccessibilityListener);
mContentResolver.unregisterContentObserver(mAssistContentObserver);
+ mDeviceProvisionedController.removeCallback(mUserSetupListener);
DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
}
@@ -505,8 +513,6 @@
// Currently there is no accelerometer sensor on non-default display.
if (mIsOnDefaultDisplay) {
- mNavigationBarView.getRotateSuggestionButton().setListener(mRotationButtonListener);
-
final RotationButtonController rotationButtonController =
mNavigationBarView.getRotationButtonController();
rotationButtonController.addRotationCallback(mRotationWatcher);
@@ -1299,6 +1305,7 @@
if (mAutoHideController != null) {
mAutoHideController.setNavigationBar(mAutoHideUiElement);
}
+ mNavigationBarView.setAutoHideController(autoHideController);
}
private boolean isTransientShown() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 9d95c30..93d4a5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -126,6 +126,7 @@
private boolean mDeadZoneConsuming = false;
private final NavigationBarTransitions mBarTransitions;
private final OverviewProxyService mOverviewProxyService;
+ private AutoHideController mAutoHideController;
// performs manual animation in sync with layout transitions
private final NavTransitionListener mTransitionListener = new NavTransitionListener();
@@ -271,6 +272,15 @@
info.touchableRegion.setEmpty();
};
+ private final Consumer<Boolean> mRotationButtonListener = (visible) -> {
+ if (visible) {
+ // If the button will actually become visible and the navbar is about to hide,
+ // tell the statusbar to keep it around for longer
+ mAutoHideController.touchAutoHide();
+ }
+ notifyActiveTouchRegions();
+ };
+
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -301,7 +311,8 @@
mFloatingRotationButton = new FloatingRotationButton(context);
mRotationButtonController = new RotationButtonController(context,
R.style.RotateButtonCCWStart90,
- isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton);
+ isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton,
+ mRotationButtonListener);
mConfiguration = new Configuration();
mTmpLastConfiguration = new Configuration();
@@ -349,6 +360,10 @@
});
}
+ public void setAutoHideController(AutoHideController autoHideController) {
+ mAutoHideController = autoHideController;
+ }
+
public NavigationBarTransitions getBarTransitions() {
return mBarTransitions;
}
@@ -936,7 +951,15 @@
updateButtonLocation(getBackButton());
updateButtonLocation(getHomeButton());
updateButtonLocation(getRecentsButton());
- updateButtonLocation(getRotateSuggestionButton());
+ updateButtonLocation(getImeSwitchButton());
+ updateButtonLocation(getAccessibilityButton());
+ if (mFloatingRotationButton.isVisible()) {
+ View floatingRotationView = mFloatingRotationButton.getCurrentView();
+ floatingRotationView.getBoundsOnScreen(mTmpBounds);
+ mActiveRegion.op(mTmpBounds, Op.UNION);
+ } else {
+ updateButtonLocation(getRotateSuggestionButton());
+ }
mOverviewProxyService.onActiveNavBarRegionChanges(mActiveRegion);
}
@@ -1208,6 +1231,7 @@
dumpButton(pw, "rcnt", getRecentsButton());
dumpButton(pw, "rota", getRotateSuggestionButton());
dumpButton(pw, "a11y", getAccessibilityButton());
+ dumpButton(pw, "ime", getImeSwitchButton());
pw.println(" }");
pw.println(" mScreenOn: " + mScreenOn);
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 64202d2..799e16c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -2612,6 +2612,7 @@
super.onClosingFinished();
resetHorizontalPanelPosition();
setClosingWithAlphaFadeout(false);
+ mMediaHierarchyManager.closeGuts();
}
private void setClosingWithAlphaFadeout(boolean closing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 01b6fbf..4e71a7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -284,13 +284,22 @@
mResources.getString(R.string.accessibility_data_saver_on));
mIconController.setIconVisibility(mSlotDataSaver, false);
+
// privacy items
+ String microphoneString = mResources.getString(PrivacyType.TYPE_MICROPHONE.getNameId());
+ String microphoneDesc = mResources.getString(
+ R.string.ongoing_privacy_chip_content_multiple_apps, microphoneString);
mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(),
- mResources.getString(PrivacyType.TYPE_MICROPHONE.getNameId()));
+ microphoneDesc);
mIconController.setIconVisibility(mSlotMicrophone, false);
+
+ String cameraString = mResources.getString(PrivacyType.TYPE_CAMERA.getNameId());
+ String cameraDesc = mResources.getString(
+ R.string.ongoing_privacy_chip_content_multiple_apps, cameraString);
mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(),
- mResources.getString(PrivacyType.TYPE_CAMERA.getNameId()));
+ cameraDesc);
mIconController.setIconVisibility(mSlotCamera, false);
+
mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
mResources.getString(R.string.accessibility_location_active));
mIconController.setIconVisibility(mSlotLocation, false);
@@ -631,7 +640,7 @@
}
@Override // PrivacyItemController.Callback
- public void privacyChanged(List<PrivacyItem> privacyItems) {
+ public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) {
updatePrivacyItems(privacyItems);
}
@@ -664,16 +673,18 @@
mIconController.setIconVisibility(mSlotCamera, showCamera);
mIconController.setIconVisibility(mSlotMicrophone, showMicrophone);
- mIconController.setIconVisibility(mSlotLocation, showLocation);
+ if (mPrivacyItemController.getAllIndicatorsAvailable()) {
+ mIconController.setIconVisibility(mSlotLocation, showLocation);
+ }
}
@Override
public void onLocationActiveChanged(boolean active) {
- if (!mPrivacyItemController.isPermissionsHubEnabled()) updateLocation();
+ if (!mPrivacyItemController.getAllIndicatorsAvailable()) updateLocationFromController();
}
// Updates the status view based on the current state of location requests.
- private void updateLocation() {
+ private void updateLocationFromController() {
if (mLocationController.isLocationActive()) {
mIconController.setIconVisibility(mSlotLocation, true);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java
index 2580c0e..281207b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java
@@ -20,9 +20,12 @@
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import java.util.function.Consumer;
+
/** Interface of a rotation button that interacts {@link RotationButtonController}. */
interface RotationButton {
void setRotationButtonController(RotationButtonController rotationButtonController);
+ void setVisibilityChangedCallback(Consumer<Boolean> visibilityChangedCallback);
View getCurrentView();
boolean show();
boolean hide();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
index 59b10e4..dbf5aa7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
@@ -117,7 +117,8 @@
return (disable2Flags & StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS) != 0;
}
- RotationButtonController(Context context, @StyleRes int style, RotationButton rotationButton) {
+ RotationButtonController(Context context, @StyleRes int style, RotationButton rotationButton,
+ Consumer<Boolean> visibilityChangedCallback) {
mContext = context;
mRotationButton = rotationButton;
mRotationButton.setRotationButtonController(this);
@@ -131,6 +132,7 @@
mTaskStackListener = new TaskStackListenerImpl();
mRotationButton.setOnClickListener(this::onRotateSuggestionClick);
mRotationButton.setOnHoverListener(this::onRotateSuggestionHover);
+ mRotationButton.setVisibilityChangedCallback(visibilityChangedCallback);
}
void registerListeners() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
index bd96752..687c223 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -26,6 +26,8 @@
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import java.util.function.Consumer;
+
/** Containing logic for the rotation button in nav bar. */
public class RotationContextButton extends ContextualButton implements
NavigationModeController.ModeChangedListener, RotationButton {
@@ -44,6 +46,18 @@
}
@Override
+ public void setVisibilityChangedCallback(Consumer<Boolean> visibilityChangedCallback) {
+ setListener(new ContextButtonListener() {
+ @Override
+ public void onVisibilityChanged(ContextualButton button, boolean visible) {
+ if (visibilityChangedCallback != null) {
+ visibilityChangedCallback.accept(visible);
+ }
+ }
+ });
+ }
+
+ @Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 673549a..e5a4679 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -79,6 +79,13 @@
default void setReverseState(boolean isReverse) {}
/**
+ * Returns {@code true} if extreme battery saver is on.
+ */
+ default boolean isExtremeSaverOn() {
+ return false;
+ }
+
+ /**
* A listener that will be notified whenever a change in battery level or power save mode has
* occurred.
*/
@@ -92,6 +99,9 @@
default void onReverseChanged(boolean isReverse, int level, String name) {
}
+
+ default void onExtremeBatterySaverChanged(boolean isExtreme) {
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 5257ce4..4ae9665 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -84,7 +84,7 @@
R.bool.config_showWifiIndicatorWhenEnabled);
boolean wifiVisible = mCurrentState.enabled && (
(mCurrentState.connected && mCurrentState.inetCondition == 1)
- || !mHasMobileDataFeature || mWifiTracker.isDefaultNetwork
+ || !mHasMobileDataFeature || mCurrentState.isDefault
|| visibleWhenEnabled);
String wifiDesc = mCurrentState.connected ? mCurrentState.ssid : null;
boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
@@ -107,6 +107,7 @@
public void fetchInitialState() {
mWifiTracker.fetchInitialState();
mCurrentState.enabled = mWifiTracker.enabled;
+ mCurrentState.isDefault = mWifiTracker.isDefaultNetwork;
mCurrentState.connected = mWifiTracker.connected;
mCurrentState.ssid = mWifiTracker.ssid;
mCurrentState.rssi = mWifiTracker.rssi;
@@ -121,6 +122,7 @@
public void handleBroadcast(Intent intent) {
mWifiTracker.handleBroadcast(intent);
mCurrentState.enabled = mWifiTracker.enabled;
+ mCurrentState.isDefault = mWifiTracker.isDefaultNetwork;
mCurrentState.connected = mWifiTracker.connected;
mCurrentState.ssid = mWifiTracker.ssid;
mCurrentState.rssi = mWifiTracker.rssi;
@@ -131,6 +133,7 @@
private void handleStatusUpdated() {
mCurrentState.statusLabel = mWifiTracker.statusLabel;
+ mCurrentState.isDefault = mWifiTracker.isDefaultNetwork;
notifyListenersIfNecessary();
}
@@ -156,6 +159,7 @@
static class WifiState extends SignalController.State {
String ssid;
boolean isTransient;
+ boolean isDefault;
String statusLabel;
@Override
@@ -164,6 +168,7 @@
WifiState state = (WifiState) s;
ssid = state.ssid;
isTransient = state.isTransient;
+ isDefault = state.isDefault;
statusLabel = state.statusLabel;
}
@@ -172,6 +177,7 @@
super.toString(builder);
builder.append(",ssid=").append(ssid)
.append(",isTransient=").append(isTransient)
+ .append(",isDefault=").append(isDefault)
.append(",statusLabel=").append(statusLabel);
}
@@ -183,6 +189,7 @@
WifiState other = (WifiState) o;
return Objects.equals(other.ssid, ssid)
&& other.isTransient == isTransient
+ && other.isDefault == isDefault
&& TextUtils.equals(other.statusLabel, statusLabel);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 9ad2aa2..2512257 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -63,7 +63,8 @@
private static final String[] RESET_BLACKLIST = new String[] {
QSTileHost.TILES_SETTING,
Settings.Secure.DOZE_ALWAYS_ON,
- Settings.Secure.MEDIA_CONTROLS_RESUME
+ Settings.Secure.MEDIA_CONTROLS_RESUME,
+ Secure.MEDIA_CONTROLS_RESUME_BLOCKED
};
private final Observer mObserver = new Observer();
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 9e3fcc4..21f7a85 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -21,12 +21,15 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.provider.Settings;
+import android.text.TextUtils;
import android.view.View;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.function.Consumer;
public class Utils {
@@ -141,4 +144,21 @@
Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
return useQsMediaPlayer(context) && flag > 0;
}
+
+ /**
+ * Get the set of apps for which the user has manually disabled resumption.
+ */
+ public static Set<String> getBlockedMediaApps(Context context) {
+ String list = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED);
+ if (TextUtils.isEmpty(list)) {
+ return new HashSet<>();
+ }
+ String[] names = list.split(":");
+ Set<String> apps = new HashSet<>(names.length);
+ for (String s : names) {
+ apps.add(s);
+ }
+ return apps;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
index 016f4de..2a5424c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
@@ -20,6 +20,7 @@
import android.util.ArrayMap
import android.util.Log
import android.view.View
+import androidx.dynamicanimation.animation.AnimationHandler
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FlingAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -124,6 +125,12 @@
private var defaultFling: FlingConfig = globalDefaultFling
/**
+ * AnimationHandler to use if it need custom AnimationHandler, if this is null, it will use
+ * the default AnimationHandler in the DynamicAnimation.
+ */
+ private var customAnimationHandler: AnimationHandler? = null
+
+ /**
* Internal listeners that respond to DynamicAnimations updating and ending, and dispatch to
* the listeners provided via [addUpdateListener] and [addEndListener]. This allows us to add
* just one permanent update and end listener to the DynamicAnimations.
@@ -447,6 +454,14 @@
this.defaultFling = defaultFling
}
+ /**
+ * Set the custom AnimationHandler for all aniatmion in this animator. Set this with null for
+ * restoring to default AnimationHandler.
+ */
+ fun setCustomAnimationHandler(handler: AnimationHandler) {
+ this.customAnimationHandler = handler
+ }
+
/** Starts the animations! */
fun start() {
startAction()
@@ -501,10 +516,13 @@
// springs) on this property before flinging.
cancel(animatedProperty)
+ // Apply the custom animation handler if it not null
+ val flingAnim = getFlingAnimation(animatedProperty, target)
+ flingAnim.animationHandler =
+ customAnimationHandler ?: flingAnim.animationHandler
+
// Apply the configuration and start the animation.
- getFlingAnimation(animatedProperty, target)
- .also { flingConfig.applyToAnimation(it) }
- .start()
+ flingAnim.also { flingConfig.applyToAnimation(it) }.start()
}
}
@@ -516,6 +534,21 @@
if (flingConfig == null) {
// Apply the configuration and start the animation.
val springAnim = getSpringAnimation(animatedProperty, target)
+
+ // If customAnimationHander is exist and has not been set to the animation,
+ // it should set here.
+ if (customAnimationHandler != null &&
+ springAnim.animationHandler != customAnimationHandler) {
+ // Cancel the animation before set animation handler
+ if (springAnim.isRunning) {
+ cancel(animatedProperty)
+ }
+ // Apply the custom animation handler if it not null
+ springAnim.animationHandler =
+ customAnimationHandler ?: springAnim.animationHandler
+ }
+
+ // Apply the configuration and start the animation.
springConfig.applyToAnimation(springAnim)
animationStartActions.add(springAnim::start)
} else {
@@ -570,10 +603,13 @@
}
}
+ // Apply the custom animation handler if it not null
+ val springAnim = getSpringAnimation(animatedProperty, target)
+ springAnim.animationHandler =
+ customAnimationHandler ?: springAnim.animationHandler
+
// Apply the configuration and start the spring animation.
- getSpringAnimation(animatedProperty, target)
- .also { springConfig.applyToAnimation(it) }
- .start()
+ springAnim.also { springConfig.applyToAnimation(it) }.start()
}
}
})
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 3455ff4..6fe11ed 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -935,6 +935,7 @@
protected void onStateChangedH(State state) {
if (D.BUG) Log.d(TAG, "onStateChangedH() state: " + state.toString());
if (mState != null && state != null
+ && mState.ringerModeInternal != -1
&& mState.ringerModeInternal != state.ringerModeInternal
&& state.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 60f0cd9..e967a5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -82,8 +82,7 @@
allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
- mFsc = new ForegroundServiceController(
- mEntryManager, mAppOpsController, mMainHandler);
+ mFsc = new ForegroundServiceController(mAppOpsController, mMainHandler);
mListener = new ForegroundServiceNotificationListener(
mContext, mFsc, mEntryManager, mNotifPipeline,
mock(ForegroundServiceLifetimeExtender.class), mClock);
@@ -115,85 +114,6 @@
}
@Test
- public void testAppOps_appOpChangedBeforeNotificationExists() {
- // GIVEN app op exists, but notification doesn't exist in NEM yet
- NotificationEntry entry = createFgEntry();
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
- assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // WHEN the notification is added
- mEntryListener.onPendingEntryAdded(entry);
-
- // THEN the app op is added to the entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
- }
-
- @Test
- public void testAppOps_appOpAddedToForegroundNotif() {
- // GIVEN a notification associated with a foreground service
- NotificationEntry entry = addFgEntry();
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry);
-
- // WHEN we are notified of a new app op for this notification
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN the app op is added to the entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views are updated since the notification is visible
- verify(mEntryManager, times(1)).updateNotifications(anyString());
- }
-
- @Test
- public void testAppOpsAlreadyAdded() {
- // GIVEN a foreground service associated notification that already has the correct app op
- NotificationEntry entry = addFgEntry();
- entry.mActiveAppOps.add(AppOpsManager.OP_CAMERA);
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry);
-
- // WHEN we are notified of the same app op for this notification
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN the app op still exists in the notification entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views aren't updated since nothing changed
- verify(mEntryManager, never()).updateNotifications(anyString());
- }
-
- @Test
- public void testAppOps_appOpNotAddedToUnrelatedNotif() {
- // GIVEN no notification entries correspond to the newly updated appOp
- NotificationEntry entry = addFgEntry();
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(null);
-
- // WHEN a new app op is detected
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN we won't see appOps on the entry
- Assert.assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views aren't updated since nothing changed
- verify(mEntryManager, never()).updateNotifications(anyString());
- }
-
- @Test
public void testAppOpsCRUD() {
// no crash on remove that doesn't exist
mFsc.onAppOpChanged(9, 1000, "pkg1", false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index 4fdc06e..8f082c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -27,6 +27,9 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -34,6 +37,8 @@
import android.app.AppOpsManager;
import android.content.pm.PackageManager;
+import android.media.AudioManager;
+import android.media.AudioRecordingConfiguration;
import android.os.Looper;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
@@ -47,9 +52,11 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Collections;
import java.util.List;
@SmallTest
@@ -73,6 +80,12 @@
private PermissionFlagsCache mFlagsCache;
@Mock
private PackageManager mPackageManager;
+ @Mock(stubOnly = true)
+ private AudioManager mAudioManager;
+ @Mock(stubOnly = true)
+ private AudioManager.AudioRecordingCallback mRecordingCallback;
+ @Mock(stubOnly = true)
+ private AudioRecordingConfiguration mPausedMockRecording;
private AppOpsControllerImpl mController;
private TestableLooper mTestableLooper;
@@ -94,11 +107,20 @@
when(mFlagsCache.getPermissionFlags(anyString(), anyString(),
eq(TEST_UID_NON_USER_SENSITIVE))).thenReturn(0);
+ doAnswer((invocation) -> mRecordingCallback = invocation.getArgument(0))
+ .when(mAudioManager).registerAudioRecordingCallback(any(), any());
+ when(mPausedMockRecording.getClientUid()).thenReturn(TEST_UID);
+ when(mPausedMockRecording.isClientSilenced()).thenReturn(true);
+
+ when(mAudioManager.getActiveRecordingConfigurations())
+ .thenReturn(List.of(mPausedMockRecording));
+
mController = new AppOpsControllerImpl(
mContext,
mTestableLooper.getLooper(),
mDumpManager,
- mFlagsCache
+ mFlagsCache,
+ mAudioManager
);
}
@@ -363,6 +385,89 @@
AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
}
+ @Test
+ public void testPausedRecordingIsRetrievedOnCreation() {
+ mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
+ mTestableLooper.processAllMessages();
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+
+ verify(mCallback, never())
+ .onActiveStateChanged(anyInt(), anyInt(), anyString(), anyBoolean());
+ }
+
+ @Test
+ public void testPausedRecordingFilteredOut() {
+ mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
+ mTestableLooper.processAllMessages();
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+
+ assertTrue(mController.getActiveAppOps().isEmpty());
+ }
+
+ @Test
+ public void testOnlyRecordAudioPaused() {
+ mController.addCallback(new int[]{
+ AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_CAMERA
+ }, mCallback);
+ mTestableLooper.processAllMessages();
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, true);
+ List<AppOpItem> list = mController.getActiveAppOps();
+
+ assertEquals(1, list.size());
+ assertEquals(AppOpsManager.OP_CAMERA, list.get(0).getCode());
+ }
+
+ @Test
+ public void testUnpausedRecordingSentActive() {
+ mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
+ mTestableLooper.processAllMessages();
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ mTestableLooper.processAllMessages();
+ mRecordingCallback.onRecordingConfigChanged(Collections.emptyList());
+
+ mTestableLooper.processAllMessages();
+
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ }
+
+ @Test
+ public void testAudioPausedSentInactive() {
+ mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
+ mTestableLooper.processAllMessages();
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+
+ AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class);
+ when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER);
+ when(mockARC.isClientSilenced()).thenReturn(true);
+
+ mRecordingCallback.onRecordingConfigChanged(List.of(mockARC));
+ mTestableLooper.processAllMessages();
+
+ InOrder inOrder = inOrder(mCallback);
+ inOrder.verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ inOrder.verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, false);
+ }
+
private class TestHandler extends AppOpsControllerImpl.H {
TestHandler(Looper looper) {
mController.super(looper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
new file mode 100644
index 0000000..4d0f2ed
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.controls
+
+import android.content.ComponentName
+import android.graphics.drawable.Icon
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class CustomIconCacheTest : SysuiTestCase() {
+
+ companion object {
+ private val TEST_COMPONENT1 = ComponentName.unflattenFromString("pkg/.cls1")!!
+ private val TEST_COMPONENT2 = ComponentName.unflattenFromString("pkg/.cls2")!!
+ private const val CONTROL_ID_1 = "TEST_CONTROL_1"
+ private const val CONTROL_ID_2 = "TEST_CONTROL_2"
+ }
+
+ @Mock(stubOnly = true)
+ private lateinit var icon1: Icon
+ @Mock(stubOnly = true)
+ private lateinit var icon2: Icon
+ private lateinit var customIconCache: CustomIconCache
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ customIconCache = CustomIconCache()
+ }
+
+ @Test
+ fun testIconStoredCorrectly() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+
+ assertTrue(icon1 === customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_1))
+ }
+
+ @Test
+ fun testIconNotStoredReturnsNull() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+
+ assertNull(customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_2))
+ }
+
+ @Test
+ fun testWrongComponentReturnsNull() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+
+ assertNull(customIconCache.retrieve(TEST_COMPONENT2, CONTROL_ID_1))
+ }
+
+ @Test
+ fun testChangeComponentOldComponentIsRemoved() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+ customIconCache.store(TEST_COMPONENT2, CONTROL_ID_2, icon2)
+
+ assertNull(customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_1))
+ assertNull(customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_2))
+ }
+
+ @Test
+ fun testChangeComponentCorrectIconRetrieved() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+ customIconCache.store(TEST_COMPONENT2, CONTROL_ID_1, icon2)
+
+ assertTrue(icon2 === customIconCache.retrieve(TEST_COMPONENT2, CONTROL_ID_1))
+ }
+
+ @Test
+ fun testStoreNull() {
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, icon1)
+ customIconCache.store(TEST_COMPONENT1, CONTROL_ID_1, null)
+
+ assertNull(customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_1))
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
index ce33a8d..f0003ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
@@ -22,6 +22,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlInterface
+import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -57,6 +58,8 @@
private lateinit var callback: FavoritesModel.FavoritesModelCallback
@Mock
private lateinit var adapter: RecyclerView.Adapter<*>
+ @Mock
+ private lateinit var customIconCache: CustomIconCache
private lateinit var model: FavoritesModel
private lateinit var dividerWrapper: DividerWrapper
@@ -64,7 +67,7 @@
fun setUp() {
MockitoAnnotations.initMocks(this)
- model = FavoritesModel(TEST_COMPONENT, INITIAL_FAVORITES, callback)
+ model = FavoritesModel(customIconCache, TEST_COMPONENT, INITIAL_FAVORITES, callback)
model.attachAdapter(adapter)
dividerWrapper = model.elements.first { it is DividerWrapper } as DividerWrapper
}
@@ -89,7 +92,7 @@
@Test
fun testInitialElements() {
val expected = INITIAL_FAVORITES.map {
- ControlInfoWrapper(TEST_COMPONENT, it, true)
+ ControlInfoWrapper(TEST_COMPONENT, it, true, customIconCache::retrieve)
} + DividerWrapper()
assertEquals(expected, model.elements)
}
@@ -287,5 +290,13 @@
verify(callback).onFirstChange()
}
+ @Test
+ fun testCacheCalledWhenGettingCustomIcon() {
+ val wrapper = model.elements[0] as ControlInfoWrapper
+ wrapper.customIcon
+
+ verify(customIconCache).retrieve(TEST_COMPONENT, wrapper.controlId)
+ }
+
private fun getDividerPosition(): Int = model.elements.indexOf(dividerWrapper)
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index c63781c..8a30b00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
@@ -23,6 +24,7 @@
import android.media.MediaMetadata
import android.media.session.MediaSession
import android.media.session.PlaybackState
+import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
@@ -35,24 +37,31 @@
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
-import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
private const val KEY = "TEST_KEY"
private const val APP = "APP"
@@ -81,6 +90,8 @@
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
@Mock private lateinit var seekBarData: LiveData<SeekBarViewModel.Progress>
@Mock private lateinit var mediaViewController: MediaViewController
+ @Mock private lateinit var keyguardDismissUtil: KeyguardDismissUtil
+ @Mock private lateinit var mediaDataManager: MediaDataManager
@Mock private lateinit var expandedSet: ConstraintSet
@Mock private lateinit var collapsedSet: ConstraintSet
private lateinit var appIcon: ImageView
@@ -100,6 +111,9 @@
private lateinit var action2: ImageButton
private lateinit var action3: ImageButton
private lateinit var action4: ImageButton
+ private lateinit var settings: View
+ private lateinit var cancel: View
+ private lateinit var dismiss: View
private lateinit var session: MediaSession
private val device = MediaDeviceData(true, null, DEVICE_NAME)
@@ -114,7 +128,7 @@
whenever(mediaViewController.collapsedLayout).thenReturn(collapsedSet)
player = MediaControlPanel(context, bgExecutor, activityStarter, mediaViewController,
- seekBarViewModel)
+ seekBarViewModel, Lazy { mediaDataManager }, keyguardDismissUtil)
whenever(seekBarViewModel.progress).thenReturn(seekBarData)
// Mock out a view holder for the player to attach to.
@@ -156,6 +170,12 @@
whenever(holder.action3).thenReturn(action3)
action4 = ImageButton(context)
whenever(holder.action4).thenReturn(action4)
+ settings = View(context)
+ whenever(holder.settings).thenReturn(settings)
+ cancel = View(context)
+ whenever(holder.cancel).thenReturn(cancel)
+ dismiss = View(context)
+ whenever(holder.dismiss).thenReturn(dismiss)
// Create media session
val metadataBuilder = MediaMetadata.Builder().apply {
@@ -254,4 +274,79 @@
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isFalse()
}
+
+ @Test
+ fun longClick_gutsClosed() {
+ player.attach(holder)
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(holder.player).setOnLongClickListener(captor.capture())
+
+ captor.value.onLongClick(holder.player)
+ verify(mediaViewController).openGuts()
+ }
+
+ @Test
+ fun longClick_gutsOpen() {
+ player.attach(holder)
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(holder.player).setOnLongClickListener(captor.capture())
+
+ captor.value.onLongClick(holder.player)
+ verify(mediaViewController, never()).openGuts()
+ }
+
+ @Test
+ fun cancelButtonClick_animation() {
+ player.attach(holder)
+
+ cancel.callOnClick()
+
+ verify(mediaViewController).closeGuts(false)
+ }
+
+ @Test
+ fun settingsButtonClick() {
+ player.attach(holder)
+
+ settings.callOnClick()
+
+ val captor = ArgumentCaptor.forClass(Intent::class.java)
+ verify(activityStarter).startActivity(captor.capture(), eq(true))
+
+ assertThat(captor.value.action).isEqualTo(ACTION_MEDIA_CONTROLS_SETTINGS)
+ }
+
+ @Test
+ fun dismissButtonClick() {
+ player.attach(holder)
+ val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
+ emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
+ notificationKey = KEY)
+ player.bind(state)
+
+ dismiss.callOnClick()
+ val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java)
+ verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean())
+
+ captor.value.onDismiss()
+ verify(mediaDataManager).dismissMediaData(eq(KEY), anyLong())
+ }
+
+ @Test
+ fun dismissButtonClick_nullNotificationKey() {
+ player.attach(holder)
+ val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
+ emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null)
+ player.bind(state)
+
+ verify(keyguardDismissUtil, never())
+ .executeWhenUnlocked(
+ any(ActivityStarter.OnDismissAction::class.java),
+ ArgumentMatchers.anyBoolean()
+ )
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index 59c2d0e..568dd6aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -197,6 +197,58 @@
}
@Test
+ fun testAppBlockedFromResumption() {
+ // GIVEN that the manager has a notification with a resume action
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ val data = listener.data!!
+ assertThat(data.resumption).isFalse()
+ mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+ // and the manager should block the package from creating resume controls
+ val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app")
+ mediaDataManager.appsBlockedFromResume = blocked
+
+ // WHEN the notification is removed
+ mediaDataManager.onNotificationRemoved(KEY)
+
+ // THEN the media data is removed
+ assertThat(listener.removedKey!!).isEqualTo(KEY)
+ }
+
+ @Test
+ fun testAppUnblockedFromResumption() {
+ // GIVEN that an app was blocked from resuming
+ val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app")
+ mediaDataManager.appsBlockedFromResume = blocked
+
+ // and GIVEN that the manager has a notification from that app with a resume action
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ val data = listener.data!!
+ assertThat(data.resumption).isFalse()
+ mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+ // WHEN the app is unblocked
+ mediaDataManager.appsBlockedFromResume = mutableSetOf("com.example.app")
+
+ // and the notification is removed
+ mediaDataManager.onNotificationRemoved(KEY)
+
+ // THEN the entry will stay as a resume control
+ assertThat(listener.key!!).isEqualTo(PACKAGE_NAME)
+ assertThat(listener.oldKey!!).isEqualTo(KEY)
+ }
+
+ @Test
fun testAddResumptionControls() {
val listener = TestListener()
mediaDataManager.addListener(listener)
@@ -217,6 +269,20 @@
assertThat(data.actions).hasSize(1)
}
+ @Test
+ fun testDismissMedia_listenerCalled() {
+ val listener = mock(MediaDataManager.Listener::class.java)
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
+ mediaDataManager.dismissMediaData(KEY, 0L)
+
+ foregroundExecutor.advanceClockToLast()
+ foregroundExecutor.runAllReady()
+
+ verify(listener).onMediaDataRemoved(eq(KEY))
+ }
+
/**
* Simple implementation of [MediaDataManager.Listener] for the test.
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index 91c5ff8..d86dfa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -142,4 +142,11 @@
verify(mediaCarouselController).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
}
+
+ @Test
+ fun testCloseGutsRelayToCarousel() {
+ mediaHiearchyManager.closeGuts()
+
+ verify(mediaCarouselController).closeGuts()
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
index f404f04..70c2bba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
@@ -270,6 +270,21 @@
}
@Test
+ public void onSaveReentryBounds_restoreLastSize() {
+ final Rect oldSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+ DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+ oldSize.scale(1.25f);
+ mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldSize);
+
+ final Rect newSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+ DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+ assertEquals(oldSize.width(), newSize.width());
+ assertEquals(oldSize.height(), newSize.height());
+ }
+
+ @Test
public void onResetReentryBounds_useDefaultBounds() {
final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
@@ -299,6 +314,22 @@
assertBoundsInclusionWithMargin("restoreLastPosition", newBounds, actualBounds);
}
+ @Test
+ public void onSaveReentryBounds_componentMismatch_restoreLastSize() {
+ final Rect oldSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+ DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+ oldSize.scale(1.25f);
+ mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldSize);
+
+ mPipBoundsHandler.onResetReentryBounds(mTestComponentName2);
+ final Rect newSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+ DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+ assertEquals(oldSize.width(), newSize.width());
+ assertEquals(oldSize.height(), newSize.height());
+ }
+
private void assertBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
final Rect expectedWithMargin = new Rect(expected);
expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
index 96bb521..9f67722 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
@@ -37,6 +37,7 @@
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.pip.PipUiEventLogger;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
@@ -85,6 +86,9 @@
@Mock
private SysUiState mSysUiState;
+ @Mock
+ private PipUiEventLogger mPipUiEventLogger;
+
private PipSnapAlgorithm mPipSnapAlgorithm;
private PipMotionHelper mMotionHelper;
private PipResizeGestureHandler mPipResizeGestureHandler;
@@ -104,7 +108,7 @@
mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager,
mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler,
mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy,
- mPipSnapAlgorithm, mSysUiState);
+ mPipSnapAlgorithm, mSysUiState, mPipUiEventLogger);
mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
mPipTouchHandler.setPipMotionHelper(mMotionHelper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt
new file mode 100644
index 0000000..4ba29e6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt
@@ -0,0 +1,219 @@
+/*
+ * 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.privacy
+
+import android.os.UserManager
+import android.provider.DeviceConfig
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.appops.AppOpsController
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.DeviceConfigProxy
+import com.android.systemui.util.DeviceConfigProxyFake
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class PrivacyItemControllerFlagsTest : SysuiTestCase() {
+ companion object {
+ fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+ fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+ fun <T> any(): T = Mockito.any<T>()
+
+ private const val ALL_INDICATORS =
+ SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED
+ private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED
+ }
+
+ @Mock
+ private lateinit var appOpsController: AppOpsController
+ @Mock
+ private lateinit var callback: PrivacyItemController.Callback
+ @Mock
+ private lateinit var userManager: UserManager
+ @Mock
+ private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock
+ private lateinit var dumpManager: DumpManager
+
+ private lateinit var privacyItemController: PrivacyItemController
+ private lateinit var executor: FakeExecutor
+ private lateinit var deviceConfigProxy: DeviceConfigProxy
+
+ fun PrivacyItemController(): PrivacyItemController {
+ return PrivacyItemController(
+ appOpsController,
+ executor,
+ executor,
+ broadcastDispatcher,
+ deviceConfigProxy,
+ userManager,
+ dumpManager
+ )
+ }
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ executor = FakeExecutor(FakeSystemClock())
+ deviceConfigProxy = DeviceConfigProxyFake()
+
+ privacyItemController = PrivacyItemController()
+ privacyItemController.addCallback(callback)
+
+ executor.runAllReady()
+ }
+
+ @Test
+ fun testNotListeningByDefault() {
+ assertFalse(privacyItemController.allIndicatorsAvailable)
+ assertFalse(privacyItemController.micCameraAvailable)
+
+ verify(appOpsController, never()).addCallback(any(), any())
+ }
+
+ @Test
+ fun testMicCameraChanged() {
+ changeMicCamera(true)
+ executor.runAllReady()
+
+ verify(callback).onFlagMicCameraChanged(true)
+ verify(callback, never()).onFlagAllChanged(anyBoolean())
+
+ assertTrue(privacyItemController.micCameraAvailable)
+ assertFalse(privacyItemController.allIndicatorsAvailable)
+ }
+
+ @Test
+ fun testAllChanged() {
+ changeAll(true)
+ executor.runAllReady()
+
+ verify(callback).onFlagAllChanged(true)
+ verify(callback, never()).onFlagMicCameraChanged(anyBoolean())
+
+ assertTrue(privacyItemController.allIndicatorsAvailable)
+ assertFalse(privacyItemController.micCameraAvailable)
+ }
+
+ @Test
+ fun testBothChanged() {
+ changeAll(true)
+ changeMicCamera(true)
+ executor.runAllReady()
+
+ verify(callback, atLeastOnce()).onFlagAllChanged(true)
+ verify(callback, atLeastOnce()).onFlagMicCameraChanged(true)
+
+ assertTrue(privacyItemController.allIndicatorsAvailable)
+ assertTrue(privacyItemController.micCameraAvailable)
+ }
+
+ @Test
+ fun testAll_listeningToAll() {
+ changeAll(true)
+ executor.runAllReady()
+
+ verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any())
+ }
+
+ @Test
+ fun testMicCamera_listening() {
+ changeMicCamera(true)
+ executor.runAllReady()
+
+ verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any())
+ }
+
+ @Test
+ fun testAll_listening() {
+ changeAll(true)
+ executor.runAllReady()
+
+ verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any())
+ }
+
+ @Test
+ fun testAllFalse_notListening() {
+ changeAll(true)
+ executor.runAllReady()
+ changeAll(false)
+ executor.runAllReady()
+
+ verify(appOpsController).removeCallback(any(), any())
+ }
+
+ @Test
+ fun testSomeListening_stillListening() {
+ changeAll(true)
+ changeMicCamera(true)
+ executor.runAllReady()
+ changeAll(false)
+ executor.runAllReady()
+
+ verify(appOpsController, never()).removeCallback(any(), any())
+ }
+
+ @Test
+ fun testAllDeleted_stopListening() {
+ changeAll(true)
+ executor.runAllReady()
+ changeAll(null)
+ executor.runAllReady()
+
+ verify(appOpsController).removeCallback(any(), any())
+ }
+
+ @Test
+ fun testMicDeleted_stopListening() {
+ changeMicCamera(true)
+ executor.runAllReady()
+ changeMicCamera(null)
+ executor.runAllReady()
+
+ verify(appOpsController).removeCallback(any(), any())
+ }
+
+ private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value)
+ private fun changeAll(value: Boolean?) = changeProperty(ALL_INDICATORS, value)
+
+ private fun changeProperty(name: String, value: Boolean?) {
+ deviceConfigProxy.setProperty(
+ DeviceConfig.NAMESPACE_PRIVACY,
+ name,
+ value?.toString(),
+ false
+ )
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index 1f7baa9..5c5df26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -18,7 +18,6 @@
import android.app.ActivityManager
import android.app.AppOpsManager
-import android.content.Context
import android.content.Intent
import android.content.pm.UserInfo
import android.os.UserHandle
@@ -69,10 +68,11 @@
companion object {
val CURRENT_USER_ID = ActivityManager.getCurrentUser()
val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE
- const val SYSTEM_UID = 1000
const val TEST_PACKAGE_NAME = "test"
- const val DEVICE_SERVICES_STRING = "Device services"
- const val TAG = "PrivacyItemControllerTest"
+
+ private const val ALL_INDICATORS =
+ SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED
+ private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
fun <T> eq(value: T): T = Mockito.eq(value) ?: value
fun <T> any(): T = Mockito.any<T>()
@@ -97,14 +97,14 @@
private lateinit var executor: FakeExecutor
private lateinit var deviceConfigProxy: DeviceConfigProxy
- fun PrivacyItemController(context: Context): PrivacyItemController {
+ fun PrivacyItemController(): PrivacyItemController {
return PrivacyItemController(
- context,
appOpsController,
executor,
executor,
broadcastDispatcher,
deviceConfigProxy,
+ userManager,
dumpManager
)
}
@@ -115,12 +115,7 @@
executor = FakeExecutor(FakeSystemClock())
deviceConfigProxy = DeviceConfigProxyFake()
- appOpsController = mDependency.injectMockDependency(AppOpsController::class.java)
- mContext.addMockSystemService(UserManager::class.java, userManager)
-
- deviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
- "true", false)
+ changeAll(true)
doReturn(listOf(object : UserInfo() {
init {
@@ -128,7 +123,7 @@
}
})).`when`(userManager).getProfiles(anyInt())
- privacyItemController = PrivacyItemController(mContext)
+ privacyItemController = PrivacyItemController()
}
@Test
@@ -137,7 +132,7 @@
executor.runAllReady()
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
any())
- verify(callback).privacyChanged(anyList())
+ verify(callback).onPrivacyItemsChanged(anyList())
}
@Test
@@ -150,7 +145,7 @@
executor.runAllReady()
verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
any())
- verify(callback).privacyChanged(emptyList())
+ verify(callback).onPrivacyItemsChanged(emptyList())
}
@Test
@@ -161,7 +156,7 @@
privacyItemController.addCallback(callback)
executor.runAllReady()
- verify(callback).privacyChanged(capture(argCaptor))
+ verify(callback).onPrivacyItemsChanged(capture(argCaptor))
assertEquals(1, argCaptor.value.size)
}
@@ -204,11 +199,11 @@
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
executor.runAllReady()
- verify(callback).privacyChanged(anyList())
+ verify(callback).onPrivacyItemsChanged(anyList())
privacyItemController.addCallback(otherCallback)
executor.runAllReady()
- verify(otherCallback).privacyChanged(anyList())
+ verify(otherCallback).onPrivacyItemsChanged(anyList())
// Adding a callback should not unnecessarily call previous ones
verifyNoMoreInteractions(callback)
}
@@ -227,8 +222,8 @@
verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
executor.runAllReady()
- verify(callback).privacyChanged(anyList())
- verify(otherCallback).privacyChanged(anyList())
+ verify(callback).onPrivacyItemsChanged(anyList())
+ verify(otherCallback).onPrivacyItemsChanged(anyList())
}
@Test
@@ -246,8 +241,8 @@
privacyItemController.removeCallback(callback)
argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
executor.runAllReady()
- verify(callback, never()).privacyChanged(anyList())
- verify(otherCallback).privacyChanged(anyList())
+ verify(callback, never()).onPrivacyItemsChanged(anyList())
+ verify(otherCallback).onPrivacyItemsChanged(anyList())
}
@Test
@@ -259,7 +254,7 @@
executor.runAllReady()
executor.runAllReady()
- verify(callback).privacyChanged(capture(argCaptor))
+ verify(callback).onPrivacyItemsChanged(capture(argCaptor))
assertEquals(1, argCaptor.value.size)
assertThat(argCaptor.value, not(hasItem(nullValue())))
}
@@ -276,15 +271,59 @@
@Test
fun testNotListeningWhenIndicatorsDisabled() {
- deviceConfigProxy.setProperty(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
- "false",
- false
- )
+ changeAll(false)
privacyItemController.addCallback(callback)
executor.runAllReady()
verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS),
any())
}
+
+ @Test
+ fun testNotSendingLocationWhenOnlyMicCamera() {
+ changeAll(false)
+ changeMicCamera(true)
+ executor.runAllReady()
+
+ doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
+ AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
+ .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+
+ privacyItemController.addCallback(callback)
+ executor.runAllReady()
+
+ verify(callback).onPrivacyItemsChanged(capture(argCaptor))
+
+ assertEquals(1, argCaptor.value.size)
+ assertEquals(PrivacyType.TYPE_CAMERA, argCaptor.value[0].privacyType)
+ }
+
+ @Test
+ fun testNotUpdated_LocationChangeWhenOnlyMicCamera() {
+ doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
+ .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+
+ privacyItemController.addCallback(callback)
+ changeAll(false)
+ changeMicCamera(true)
+ executor.runAllReady()
+ reset(callback) // Clean callback
+
+ verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
+ argCaptorCallback.value.onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true)
+
+ verify(callback, never()).onPrivacyItemsChanged(any())
+ }
+
+ private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value)
+ private fun changeAll(value: Boolean?) = changeProperty(ALL_INDICATORS, value)
+
+ private fun changeProperty(name: String, value: Boolean?) {
+ deviceConfigProxy.setProperty(
+ DeviceConfig.NAMESPACE_PRIVACY,
+ name,
+ value?.toString(),
+ false
+ )
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 92a2c87..80fa8cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -211,19 +211,6 @@
}
@Test
- public void testUpdateNotificationViews_appOps() throws Exception {
- NotificationEntry entry0 = createEntry();
- entry0.setRow(spy(entry0.getRow()));
- when(mEntryManager.getVisibleNotifications()).thenReturn(
- Lists.newArrayList(entry0));
- mListContainer.addContainerView(entry0.getRow());
-
- mViewHierarchyManager.updateNotificationViews();
-
- verify(entry0.getRow(), times(1)).showAppOpsIcons(any());
- }
-
- @Test
public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() {
// GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews()
mMadeReentrantCall = false;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
index 314b191..ae39035 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
@@ -72,8 +72,6 @@
private Notification mNotification;
private AppOpsCoordinator mAppOpsCoordinator;
private NotifFilter mForegroundFilter;
- private NotifCollectionListener mNotifCollectionListener;
- private AppOpsController.Callback mAppOpsCallback;
private NotifLifetimeExtender mForegroundNotifLifetimeExtender;
private FakeSystemClock mClock = new FakeSystemClock();
@@ -110,18 +108,6 @@
lifetimeExtenderCaptor.capture());
mForegroundNotifLifetimeExtender = lifetimeExtenderCaptor.getValue();
- // capture notifCollectionListener
- ArgumentCaptor<NotifCollectionListener> notifCollectionCaptor =
- ArgumentCaptor.forClass(NotifCollectionListener.class);
- verify(mNotifPipeline, times(1)).addCollectionListener(
- notifCollectionCaptor.capture());
- mNotifCollectionListener = notifCollectionCaptor.getValue();
-
- // capture app ops callback
- ArgumentCaptor<AppOpsController.Callback> appOpsCaptor =
- ArgumentCaptor.forClass(AppOpsController.Callback.class);
- verify(mAppOpsController).addCallback(any(int[].class), appOpsCaptor.capture());
- mAppOpsCallback = appOpsCaptor.getValue();
}
@Test
@@ -215,134 +201,4 @@
assertFalse(mForegroundNotifLifetimeExtender
.shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK));
}
-
- @Test
- public void testAppOpsUpdateOnlyAppliedToRelevantNotificationWithStandardLayout() {
- // GIVEN three current notifications, two with the same key but from different users
- NotificationEntry entry1 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(1)
- .build();
- NotificationEntry entry2 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- NotificationEntry entry3_diffUser = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID + 1))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3_diffUser));
-
- // GIVEN that only entry2 has a standard layout
- when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry2.getKey())));
-
- // WHEN a new app ops code comes in
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
-
- // THEN entry2's app ops are updated, but no one else's are
- assertEquals(
- new ArraySet<>(),
- entry1.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry2.mActiveAppOps);
- assertEquals(
- new ArraySet<>(),
- entry3_diffUser.mActiveAppOps);
- }
-
- @Test
- public void testAppOpsUpdateAppliedToAllNotificationsWithStandardLayouts() {
- // GIVEN three notifications with standard layouts
- NotificationEntry entry1 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(1)
- .build();
- NotificationEntry entry2 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- NotificationEntry entry3 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(3)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3));
- when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry1.getKey(), entry2.getKey(),
- entry3.getKey())));
-
- // WHEN a new app ops code comes in
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
-
- // THEN all entries get updated
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry1.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry2.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry3.mActiveAppOps);
- }
-
- @Test
- public void testAppOpsAreRemoved() {
- // GIVEN One notification which is associated with app ops
- NotificationEntry entry = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry));
- when(mForegroundServiceController.getStandardLayoutKeys(0, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry.getKey())));
-
- // GIVEN that the notification's app ops are already [47, 33]
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mAppOpsCallback.onActiveStateChanged(33, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
- assertEquals(
- new ArraySet<>(List.of(47, 33)),
- entry.mActiveAppOps);
-
- // WHEN one of the app ops is removed
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, false);
- mExecutor.runAllReady();
-
- // THEN the entry's active app ops are updated as well
- assertEquals(
- new ArraySet<>(List.of(33)),
- entry.mActiveAppOps);
- }
-
- @Test
- public void testNullAppOps() {
- // GIVEN one notification with app ops
- NotificationEntry entry = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- entry.mActiveAppOps.clear();
- entry.mActiveAppOps.addAll(List.of(47, 33));
-
- // WHEN the notification is updated and the foreground service controller returns null for
- // this notification
- when(mForegroundServiceController.getAppOps(entry.getSbn().getUser().getIdentifier(),
- entry.getSbn().getPackageName())).thenReturn(null);
- mNotifCollectionListener.onEntryUpdated(entry);
-
- // THEN the entry's active app ops is updated to empty
- assertTrue(entry.mActiveAppOps.isEmpty());
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
deleted file mode 100644
index 43d8b50..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.notification.row;
-
-import static android.app.AppOpsManager.OP_CAMERA;
-import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.UiThreadTest;
-import android.util.ArraySet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@UiThreadTest
-public class AppOpsInfoTest extends SysuiTestCase {
- private static final String TEST_PACKAGE_NAME = "test_package";
- private static final int TEST_UID = 1;
-
- private AppOpsInfo mAppOpsInfo;
- private final PackageManager mMockPackageManager = mock(PackageManager.class);
- private final NotificationGuts mGutsParent = mock(NotificationGuts.class);
- private StatusBarNotification mSbn;
- private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
-
- @Before
- public void setUp() throws Exception {
- // Inflate the layout
- final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
- mAppOpsInfo = (AppOpsInfo) layoutInflater.inflate(R.layout.app_ops_info, null);
- mAppOpsInfo.setGutsParent(mGutsParent);
-
- // PackageManager must return a packageInfo and applicationInfo.
- final PackageInfo packageInfo = new PackageInfo();
- packageInfo.packageName = TEST_PACKAGE_NAME;
- when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
- .thenReturn(packageInfo);
- final ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.uid = TEST_UID; // non-zero
- when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(
- applicationInfo);
-
- mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
- new Notification(), UserHandle.CURRENT, null, 0);
- }
-
- @Test
- public void testBindNotification_SetsTextApplicationName() {
- when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname);
- assertTrue(textView.getText().toString().contains("App Name"));
- }
-
- @Test
- public void testBindNotification_SetsPackageIcon() {
- final Drawable iconDrawable = mock(Drawable.class);
- when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
- .thenReturn(iconDrawable);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon);
- assertEquals(iconDrawable, iconView.getDrawable());
- }
-
- @Test
- public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- final CountDownLatch latch = new CountDownLatch(1);
- mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid,
- ArraySet<Integer> ops) -> {
- assertEquals(TEST_PACKAGE_NAME, pkg);
- assertEquals(expectedOps, ops);
- assertEquals(TEST_UID, uid);
- latch.countDown();
- }, mSbn, mUiEventLogger, expectedOps);
-
- final View settingsButton = mAppOpsInfo.findViewById(R.id.settings);
- settingsButton.performClick();
- // Verify that listener was triggered.
- assertEquals(0, latch.getCount());
- }
-
- @Test
- public void testBindNotification_LogsOpen() throws Exception {
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- assertEquals(1, mUiEventLogger.numLogs());
- assertEquals(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN.getId(),
- mUiEventLogger.eventId(0));
- }
-
- @Test
- public void testOk() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- final CountDownLatch latch = new CountDownLatch(1);
- mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid,
- ArraySet<Integer> ops) -> {
- assertEquals(TEST_PACKAGE_NAME, pkg);
- assertEquals(expectedOps, ops);
- assertEquals(TEST_UID, uid);
- latch.countDown();
- }, mSbn, mUiEventLogger, expectedOps);
-
- final View okButton = mAppOpsInfo.findViewById(R.id.ok);
- okButton.performClick();
- assertEquals(1, latch.getCount());
- verify(mGutsParent, times(1)).closeControls(eq(okButton), anyBoolean());
- }
-
- @Test
- public void testPrompt_camera() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_mic() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the microphone.", prompt.getText());
- }
-
- @Test
- public void testPrompt_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_mic() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the microphone and camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_mic_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_RECORD_AUDIO);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the microphone and camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_mic_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_RECORD_AUDIO);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the microphone.", prompt.getText());
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 2684cc2..4758d23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -35,12 +35,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.AppOpsManager;
import android.app.NotificationChannel;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.ArraySet;
import android.view.View;
import androidx.test.filters.SmallTest;
@@ -213,46 +211,6 @@
}
@Test
- public void testShowAppOps_noHeader() {
- // public notification is custom layout - no header
- mGroupRow.setSensitive(true, true);
- mGroupRow.setAppOpsOnClickListener(null);
- mGroupRow.showAppOpsIcons(null);
- }
-
- @Test
- public void testShowAppOpsIcons_header() {
- NotificationContentView publicLayout = mock(NotificationContentView.class);
- mGroupRow.setPublicLayout(publicLayout);
- NotificationContentView privateLayout = mock(NotificationContentView.class);
- mGroupRow.setPrivateLayout(privateLayout);
- NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
- when(mockContainer.getNotificationChildCount()).thenReturn(1);
- mGroupRow.setChildrenContainer(mockContainer);
-
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
- mGroupRow.showAppOpsIcons(ops);
-
- verify(mockContainer, times(1)).showAppOpsIcons(ops);
- verify(privateLayout, times(1)).showAppOpsIcons(ops);
- verify(publicLayout, times(1)).showAppOpsIcons(ops);
-
- }
-
- @Test
- public void testAppOpsOnClick() {
- ExpandableNotificationRow.OnAppOpsClickListener l = mock(
- ExpandableNotificationRow.OnAppOpsClickListener.class);
- View view = mock(View.class);
-
- mGroupRow.setAppOpsOnClickListener(l);
-
- mGroupRow.getAppOpsOnClickListener().onClick(view);
- verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any());
- }
-
- @Test
public void testHeadsUpAnimatingAwayListener() {
mGroupRow.setHeadsUpAnimatingAway(true);
Assert.assertEquals(true, mHeadsUpAnimatingAway);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
index ed4f8b3..b02f274 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
@@ -76,32 +76,6 @@
@Test
@UiThreadTest
- public void testShowAppOpsIcons() {
- View mockContracted = mock(NotificationHeaderView.class);
- when(mockContracted.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockContracted);
- View mockExpanded = mock(NotificationHeaderView.class);
- when(mockExpanded.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockExpanded);
- View mockHeadsUp = mock(NotificationHeaderView.class);
- when(mockHeadsUp.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockHeadsUp);
-
- mView.setContractedChild(mockContracted);
- mView.setExpandedChild(mockExpanded);
- mView.setHeadsUpChild(mockHeadsUp);
-
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(AppOpsManager.OP_RECORD_AUDIO);
- mView.showAppOpsIcons(ops);
-
- verify(mockContracted, times(1)).setVisibility(View.VISIBLE);
- verify(mockExpanded, times(1)).setVisibility(View.VISIBLE);
- verify(mockHeadsUp, times(1)).setVisibility(View.VISIBLE);
- }
-
- @Test
- @UiThreadTest
public void testExpandButtonFocusIsCalled() {
View mockContractedEB = mock(NotificationExpandButton.class);
View mockContracted = mock(NotificationHeaderView.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 0c6409b..d2ff2ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -421,7 +421,6 @@
mBindStage,
mock(OnExpandClickListener.class),
mock(NotificationMediaManager.class),
- mock(ExpandableNotificationRow.OnAppOpsClickListener.class),
mock(FalsingManager.class),
mStatusBarStateController,
mPeopleNotificationIdentifier);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
index d6b38ff..1b1ea31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
@@ -60,7 +60,8 @@
final View view = new View(mContext);
mRotationButton = mock(RotationButton.class);
mRotationButtonController = spy(
- new RotationButtonController(mContext, RES_UNDEF, mRotationButton));
+ new RotationButtonController(mContext, RES_UNDEF, mRotationButton,
+ (visibility) -> {}));
final KeyButtonDrawable kbd = mock(KeyButtonDrawable.class);
doReturn(view).when(mRotationButton).getCurrentView();
doReturn(true).when(mRotationButton).acceptRotationProposal();
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index b0e401b..3f712dd 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -3706,33 +3706,40 @@
// OS: O
BACKUP_SETTINGS = 818;
+ // DEPRECATED: The metrics has been migrated to UiEvent per go/uievent.
// ACTION: Picture-in-picture was explicitly entered for an activity
// VALUE: true if it was entered while hiding as a result of moving to
// another task, false otherwise
- ACTION_PICTURE_IN_PICTURE_ENTERED = 819;
+ ACTION_PICTURE_IN_PICTURE_ENTERED = 819 [deprecated=true];
+ // DEPRECATED: The metrics has been migrated to UiEvent per go/uievent.
// ACTION: The activity currently in picture-in-picture was expanded back to fullscreen
// PACKAGE: The package name of the activity that was expanded back to fullscreen
- ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN = 820;
+ ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN = 820 [deprecated=true];
+ // DEPRECATED: The metrics no longer used after migration to UiEvent per go/uievent.
// ACTION: The activity currently in picture-in-picture was minimized
// VALUE: True if the PiP was minimized, false otherwise
- ACTION_PICTURE_IN_PICTURE_MINIMIZED = 821;
+ ACTION_PICTURE_IN_PICTURE_MINIMIZED = 821 [deprecated=true];
+ // DEPRECATED: The metrics has been migrated to UiEvent per go/uievent.
// ACTION: Picture-in-picture was dismissed via the dismiss button
// VALUE: 0 if dismissed by tap, 1 if dismissed by drag
- ACTION_PICTURE_IN_PICTURE_DISMISSED = 822;
+ ACTION_PICTURE_IN_PICTURE_DISMISSED = 822 [deprecated=true];
- // ACTION: The visibility of the picture-in-picture meny
+ // DEPRECATED: The metrics has been migrated to UiEvent per go/uievent.
+ // ACTION: The visibility of the picture-in-picture menu
// VALUE: Whether or not the menu is visible
- ACTION_PICTURE_IN_PICTURE_MENU = 823;
+ ACTION_PICTURE_IN_PICTURE_MENU = 823 [deprecated=true];
+ // DEPRECATED: The metrics has been migrated to UiEvent per go/uievent.
// Enclosing category for group of PICTURE_IN_PICTURE_ASPECT_RATIO_FOO events,
// logged when the aspect ratio changes
- ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED = 824;
+ ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED = 824 [deprecated=true];
+ // DEPRECATED: The metrics no longer used after migration to UiEvent per go/uievent.
// The current aspect ratio of the PiP, logged when it changes.
- PICTURE_IN_PICTURE_ASPECT_RATIO = 825;
+ PICTURE_IN_PICTURE_ASPECT_RATIO = 825 [deprecated=true];
// FIELD - length in dp of ACTION_LS_* gestures, or zero if not applicable
// CATEGORY: GLOBAL_SYSTEM_UI
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index 1c4db12..59ba82e 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -34,6 +34,7 @@
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
+import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.util.Slog;
@@ -108,9 +109,9 @@
@Override
public void createPredictionSession(@NonNull AppPredictionContext context,
- @NonNull AppPredictionSessionId sessionId) {
- runForUserLocked("createPredictionSession", sessionId,
- (service) -> service.onCreatePredictionSessionLocked(context, sessionId));
+ @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
+ runForUserLocked("createPredictionSession", sessionId, (service) ->
+ service.onCreatePredictionSessionLocked(context, sessionId, token));
}
@Override
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 103151d..f9cd60a 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.ServiceInfo;
+import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.provider.DeviceConfig;
@@ -44,8 +45,6 @@
import com.android.server.infra.AbstractPerUserSystemService;
import com.android.server.people.PeopleServiceInternal;
-import java.util.function.Consumer;
-
/**
* Per-user instance of {@link AppPredictionManagerService}.
*/
@@ -112,17 +111,24 @@
*/
@GuardedBy("mLock")
public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context,
- @NonNull AppPredictionSessionId sessionId) {
- if (!mSessionInfos.containsKey(sessionId)) {
- mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context,
- DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
- PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false),
- this::removeAppPredictionSessionInfo));
- }
- final boolean serviceExists = resolveService(sessionId, s ->
- s.onCreatePredictionSession(context, sessionId), true);
- if (!serviceExists) {
- mSessionInfos.remove(sessionId);
+ @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
+ final boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
+ PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false);
+ final boolean serviceExists = resolveService(sessionId, false,
+ usesPeopleService, s -> s.onCreatePredictionSession(context, sessionId));
+ if (serviceExists && !mSessionInfos.containsKey(sessionId)) {
+ final AppPredictionSessionInfo sessionInfo = new AppPredictionSessionInfo(
+ sessionId, context, usesPeopleService, token, () -> {
+ synchronized (mLock) {
+ onDestroyPredictionSessionLocked(sessionId);
+ }
+ });
+ if (sessionInfo.linkToDeath()) {
+ mSessionInfos.put(sessionId, sessionInfo);
+ } else {
+ // destroy the session if calling process is already dead
+ onDestroyPredictionSessionLocked(sessionId);
+ }
}
}
@@ -132,7 +138,10 @@
@GuardedBy("mLock")
public void notifyAppTargetEventLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull AppTargetEvent event) {
- resolveService(sessionId, s -> s.notifyAppTargetEvent(sessionId, event), false);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.notifyAppTargetEvent(sessionId, event));
}
/**
@@ -141,8 +150,10 @@
@GuardedBy("mLock")
public void notifyLaunchLocationShownLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull String launchLocation, @NonNull ParceledListSlice targetIds) {
- resolveService(sessionId, s ->
- s.notifyLaunchLocationShown(sessionId, launchLocation, targetIds), false);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.notifyLaunchLocationShown(sessionId, launchLocation, targetIds));
}
/**
@@ -151,7 +162,10 @@
@GuardedBy("mLock")
public void sortAppTargetsLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull ParceledListSlice targets, @NonNull IPredictionCallback callback) {
- resolveService(sessionId, s -> s.sortAppTargets(sessionId, targets, callback), true);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, true, sessionInfo.mUsesPeopleService,
+ s -> s.sortAppTargets(sessionId, targets, callback));
}
/**
@@ -160,10 +174,12 @@
@GuardedBy("mLock")
public void registerPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull IPredictionCallback callback) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.registerPredictionUpdates(sessionId, callback), false);
final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId, false,
+ sessionInfo.mUsesPeopleService,
+ s -> s.registerPredictionUpdates(sessionId, callback));
+ if (serviceExists) {
sessionInfo.addCallbackLocked(callback);
}
}
@@ -174,10 +190,12 @@
@GuardedBy("mLock")
public void unregisterPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull IPredictionCallback callback) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.unregisterPredictionUpdates(sessionId, callback), false);
final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId, false,
+ sessionInfo.mUsesPeopleService,
+ s -> s.unregisterPredictionUpdates(sessionId, callback));
+ if (serviceExists) {
sessionInfo.removeCallbackLocked(callback);
}
}
@@ -187,7 +205,10 @@
*/
@GuardedBy("mLock")
public void requestPredictionUpdateLocked(@NonNull AppPredictionSessionId sessionId) {
- resolveService(sessionId, s -> s.requestPredictionUpdate(sessionId), true);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, true, sessionInfo.mUsesPeopleService,
+ s -> s.requestPredictionUpdate(sessionId));
}
/**
@@ -195,12 +216,14 @@
*/
@GuardedBy("mLock")
public void onDestroyPredictionSessionLocked(@NonNull AppPredictionSessionId sessionId) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.onDestroyPredictionSession(sessionId), false);
- final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
- sessionInfo.destroy();
+ if (isDebug()) {
+ Slog.d(TAG, "onDestroyPredictionSessionLocked(): sessionId=" + sessionId);
}
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.remove(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.onDestroyPredictionSession(sessionId));
+ sessionInfo.destroy();
}
@Override
@@ -291,27 +314,18 @@
}
for (AppPredictionSessionInfo sessionInfo : mSessionInfos.values()) {
- sessionInfo.resurrectSessionLocked(this);
- }
- }
-
- private void removeAppPredictionSessionInfo(AppPredictionSessionId sessionId) {
- if (isDebug()) {
- Slog.d(TAG, "removeAppPredictionSessionInfo(): sessionId=" + sessionId);
- }
- synchronized (mLock) {
- mSessionInfos.remove(sessionId);
+ sessionInfo.resurrectSessionLocked(this, sessionInfo.mToken);
}
}
@GuardedBy("mLock")
@Nullable
- protected boolean resolveService(@NonNull final AppPredictionSessionId sessionId,
- @NonNull final AbstractRemoteService.AsyncRequest<IPredictionService> cb,
- boolean sendImmediately) {
- final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (sessionInfo == null) return false;
- if (sessionInfo.mUsesPeopleService) {
+ protected boolean resolveService(
+ @NonNull final AppPredictionSessionId sessionId,
+ boolean sendImmediately,
+ boolean usesPeopleService,
+ @NonNull final AbstractRemoteService.AsyncRequest<IPredictionService> cb) {
+ if (usesPeopleService) {
final IPredictionService service =
LocalServices.getService(PeopleServiceInternal.class);
if (service != null) {
@@ -368,7 +382,9 @@
private final AppPredictionContext mPredictionContext;
private final boolean mUsesPeopleService;
@NonNull
- private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction;
+ final IBinder mToken;
+ @NonNull
+ final IBinder.DeathRecipient mDeathRecipient;
private final RemoteCallbackList<IPredictionCallback> mCallbacks =
new RemoteCallbackList<IPredictionCallback>() {
@@ -388,14 +404,16 @@
@NonNull final AppPredictionSessionId id,
@NonNull final AppPredictionContext predictionContext,
final boolean usesPeopleService,
- @NonNull final Consumer<AppPredictionSessionId> removeSessionInfoAction) {
+ @NonNull final IBinder token,
+ @NonNull final IBinder.DeathRecipient deathRecipient) {
if (DEBUG) {
Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id);
}
mSessionId = id;
mPredictionContext = predictionContext;
mUsesPeopleService = usesPeopleService;
- mRemoveSessionInfoAction = removeSessionInfoAction;
+ mToken = token;
+ mDeathRecipient = deathRecipient;
}
void addCallbackLocked(IPredictionCallback callback) {
@@ -414,23 +432,38 @@
mCallbacks.unregister(callback);
}
+ boolean linkToDeath() {
+ try {
+ mToken.linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Caller is dead before session can be started, sessionId: "
+ + mSessionId);
+ }
+ return false;
+ }
+ return true;
+ }
+
void destroy() {
if (DEBUG) {
Slog.d(TAG, "Removing all callbacks for session Id=" + mSessionId
+ " and " + mCallbacks.getRegisteredCallbackCount() + " callbacks.");
}
+ if (mToken != null) {
+ mToken.unlinkToDeath(mDeathRecipient, 0);
+ }
mCallbacks.kill();
- mRemoveSessionInfoAction.accept(mSessionId);
}
- void resurrectSessionLocked(AppPredictionPerUserService service) {
+ void resurrectSessionLocked(AppPredictionPerUserService service, IBinder token) {
int callbackCount = mCallbacks.getRegisteredCallbackCount();
if (DEBUG) {
Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked()
+ ") for session Id=" + mSessionId + " and "
+ callbackCount + " callbacks.");
}
- service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId);
+ service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId, token);
mCallbacks.broadcast(
callback -> service.registerPredictionUpdatesLocked(mSessionId, callback));
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 5a9320f..b0755ac 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -161,8 +161,9 @@
@Override
public void onFailure(int requestId, CharSequence message) {
+ String errorMessage = message == null ? "" : String.valueOf(message);
fillRequest.completeExceptionally(
- new RuntimeException(String.valueOf(message)));
+ new RuntimeException(errorMessage));
}
});
return fillRequest;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 77cd5d2..03c31a6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -220,6 +220,8 @@
import com.google.android.collect.Lists;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -7519,18 +7521,34 @@
public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId,
int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
String dstAddr) {
- mKeepaliveTracker.startNattKeepalive(
- getNetworkAgentInfoForNetwork(network), fd, resourceId,
- intervalSeconds, cb,
- srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
+ try {
+ mKeepaliveTracker.startNattKeepalive(
+ getNetworkAgentInfoForNetwork(network), fd, resourceId,
+ intervalSeconds, cb,
+ srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
+ } finally {
+ // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
+ // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
+ if (fd != null && Binder.getCallingPid() != Process.myPid()) {
+ IoUtils.closeQuietly(fd);
+ }
+ }
}
@Override
public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds,
ISocketKeepaliveCallback cb) {
- enforceKeepalivePermission();
- mKeepaliveTracker.startTcpKeepalive(
- getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
+ try {
+ enforceKeepalivePermission();
+ mKeepaliveTracker.startTcpKeepalive(
+ getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
+ } finally {
+ // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
+ // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
+ if (fd != null && Binder.getCallingPid() != Process.myPid()) {
+ IoUtils.closeQuietly(fd);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index a153d41..9472a8a 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -1066,18 +1066,18 @@
return attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
}
- private int getAppOpMode(Vibration vib) {
+ private int getAppOpMode(int uid, String packageName, VibrationAttributes attrs) {
int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
- vib.attrs.getAudioAttributes().getUsage(), vib.uid, vib.opPkg);
+ attrs.getAudioAttributes().getUsage(), uid, packageName);
if (mode == AppOpsManager.MODE_ALLOWED) {
- mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
+ mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, uid, packageName);
}
- if (mode == AppOpsManager.MODE_IGNORED && shouldBypassDnd(vib.attrs)) {
+ if (mode == AppOpsManager.MODE_IGNORED && shouldBypassDnd(attrs)) {
// If we're just ignoring the vibration op then this is set by DND and we should ignore
// if we're asked to bypass. AppOps won't be able to record this operation, so make
// sure we at least note it in the logs for debugging.
- Slog.d(TAG, "Bypassing DND for vibration: " + vib);
+ Slog.d(TAG, "Bypassing DND for vibrate from uid " + uid);
mode = AppOpsManager.MODE_ALLOWED;
}
return mode;
@@ -1099,7 +1099,7 @@
return false;
}
- final int mode = getAppOpMode(vib);
+ final int mode = getAppOpMode(vib.uid, vib.opPkg, vib.attrs);
if (mode != AppOpsManager.MODE_ALLOWED) {
if (mode == AppOpsManager.MODE_ERRORED) {
// We might be getting calls from within system_server, so we don't actually
@@ -1774,7 +1774,7 @@
return SCALE_MUTE;
}
if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE,
- vib.getUid(), -1 /*owningUid*/, true /*exported*/)
+ vib.getUid(), -1 /*owningUid*/, true /*exported*/)
!= PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid()
+ " tried to play externally controlled vibration"
@@ -1782,6 +1782,14 @@
return SCALE_MUTE;
}
+ int mode = getAppOpMode(vib.getUid(), vib.getPackage(), vib.getVibrationAttributes());
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ if (mode == AppOpsManager.MODE_ERRORED) {
+ Slog.w(TAG, "Would be an error: external vibrate from uid " + vib.getUid());
+ }
+ return SCALE_MUTE;
+ }
+
final int scaleLevel;
synchronized (mLock) {
if (!vib.equals(mCurrentExternalVibration)) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3f867f6..e1bb4cd 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -453,16 +453,16 @@
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
- int callingPid, int callingUid, boolean fgRequired, String callingPackage,
- @Nullable String callingFeatureId, final int userId)
+ int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification,
+ String callingPackage, @Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
- callingPackage, callingFeatureId, userId, false);
+ hideFgNotification, callingPackage, callingFeatureId, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
- int callingPid, int callingUid, boolean fgRequired, String callingPackage,
- @Nullable String callingFeatureId, final int userId,
+ int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification,
+ String callingPackage, @Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -609,6 +609,7 @@
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
+ r.hideFgNotification = hideFgNotification;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
@@ -1836,11 +1837,13 @@
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
+ " type=" + resolvedType + " conn=" + connection.asBinder()
+ " flags=0x" + Integer.toHexString(flags));
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
- + " (pid=" + Binder.getCallingPid()
+ + " (pid=" + callingPid
+ ") when binding service " + service);
}
@@ -1880,19 +1883,19 @@
}
if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 && !isCallerSystem) {
- throw new SecurityException("Non-system caller (pid=" + Binder.getCallingPid()
+ throw new SecurityException("Non-system caller (pid=" + callingPid
+ ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service);
}
if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
throw new SecurityException(
- "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
+ "Non-system caller " + caller + " (pid=" + callingPid
+ ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service);
}
if ((flags & Context.BIND_ALLOW_INSTANT) != 0 && !isCallerSystem) {
throw new SecurityException(
- "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
+ "Non-system caller " + caller + " (pid=" + callingPid
+ ") set BIND_ALLOW_INSTANT when binding service " + service);
}
@@ -1908,7 +1911,7 @@
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
- Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
+ callingPid, callingUid, userId, true,
callerFg, isBindExternal, allowInstant);
if (res == null) {
return 0;
@@ -2068,7 +2071,7 @@
if (!s.mAllowWhileInUsePermissionInFgs) {
s.mAllowWhileInUsePermissionInFgs =
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage,
- Binder.getCallingPid(), Binder.getCallingUid(),
+ callingPid, callingUid,
service, s, false);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 82abb98..491579a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1438,6 +1438,10 @@
final Injector mInjector;
+ /** The package verifier app. */
+ private String mPackageVerifier;
+ private int mPackageVerifierUid = UserHandle.USER_NULL;
+
static final class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_FOREGROUND_SERVICES = 1<<1;
@@ -2214,17 +2218,13 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(false);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"meminfo", pw)) return;
PriorityDump.dump(mPriorityDumper, fd, pw, args);
} finally {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(true);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2238,17 +2238,13 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(false);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
} finally {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(true);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2262,17 +2258,13 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(false);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
} finally {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(true);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2318,9 +2310,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(false);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"cacheinfo", pw)) {
@@ -2329,9 +2319,7 @@
mActivityManagerService.dumpBinderCacheContents(fd, pw, args);
} finally {
- if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
- Process.enableFreezer(true);
- }
+ mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2362,6 +2350,18 @@
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mService.mBatteryStatsService.systemServicesReady();
mService.mServices.systemServicesReady();
+ mService.mPackageVerifier = ArrayUtils.firstOrNull(
+ LocalServices.getService(PackageManagerInternal.class).getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM));
+ if (mService.mPackageVerifier != null) {
+ try {
+ mService.mPackageVerifierUid =
+ getContext().getPackageManager().getPackageUid(
+ mService.mPackageVerifier, UserHandle.USER_SYSTEM);
+ } catch (NameNotFoundException e) {
+ Slog.wtf(TAG, "Package manager couldn't get package verifier uid", e);
+ }
+ }
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
@@ -15007,8 +15007,8 @@
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, boolean requireForeground, String callingPackage,
- String callingFeatureId, int userId)
+ String resolvedType, boolean requireForeground, boolean hideForegroundNotification,
+ String callingPackage, String callingFeatureId, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
@@ -15020,17 +15020,27 @@
throw new IllegalArgumentException("callingPackage cannot be null");
}
+ final int callingUid = Binder.getCallingUid();
+ if (requireForeground && hideForegroundNotification) {
+ if (!UserHandle.isSameApp(callingUid, mPackageVerifierUid)
+ || !callingPackage.equals(mPackageVerifier)) {
+ throw new IllegalArgumentException(
+ "Only the package verifier can hide its foreground service notification");
+ }
+ Slog.i(TAG, "Foreground service notification hiding requested by " + callingPackage);
+ }
+
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
- requireForeground, callingPackage, callingFeatureId, userId);
+ requireForeground, hideForegroundNotification,
+ callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -18604,14 +18614,14 @@
}
}
- Process.enableFreezer(false);
+ mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
final RemoteCallback intermediateCallback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
finishCallback.sendResult(result);
- Process.enableFreezer(true);
+ mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}, null);
@@ -19470,7 +19480,7 @@
ComponentName res;
try {
res = mServices.startServiceLocked(null, service,
- resolvedType, -1, uid, fgRequired, callingPackage,
+ resolvedType, -1, uid, fgRequired, false, callingPackage,
callingFeatureId, userId, allowBackgroundActivityStarts);
} finally {
Binder.restoreCallingIdentity(origId);
@@ -20373,4 +20383,16 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public boolean enableAppFreezer(boolean enable) {
+ int callerUid = Binder.getCallingUid();
+
+ // Only system can toggle the freezer state
+ if (callerUid == SYSTEM_UID) {
+ return mOomAdjuster.mCachedAppOptimizer.enableFreezer(enable);
+ } else {
+ throw new SecurityException("Caller uid " + callerUid + " cannot set freezer state ");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 149e3ba..a512cca 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -654,7 +654,7 @@
pw.println("Starting service: " + intent);
pw.flush();
ComponentName cn = mInterface.startService(null, intent, intent.getType(),
- asForeground, SHELL_PACKAGE_NAME, null, mUserId);
+ asForeground, false, SHELL_PACKAGE_NAME, null, mUserId);
if (cn == null) {
err.println("Error: Not found; no service started.");
return -1;
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index d9fde0f..c5047e5 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -208,6 +208,8 @@
@GuardedBy("mPhenotypeFlagLock")
private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION;
private volatile boolean mUseFreezer = DEFAULT_USE_FREEZER;
+ @GuardedBy("this")
+ private int mFreezerDisableCount = 1; // Freezer is initially disabled, until enabled
private final Random mRandom = new Random();
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting volatile float mCompactStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE;
@@ -420,25 +422,82 @@
}
/**
- * Determines whether the freezer is correctly supported by this system
+ * Enables or disabled the app freezer.
+ * @param enable Enables the freezer if true, disables it if false.
+ * @return true if the operation completed successfully, false otherwise.
+ */
+ public synchronized boolean enableFreezer(boolean enable) {
+ if (!mUseFreezer) {
+ return false;
+ }
+
+ if (enable) {
+ mFreezerDisableCount--;
+
+ if (mFreezerDisableCount > 0) {
+ return true;
+ } else if (mFreezerDisableCount < 0) {
+ Slog.e(TAG_AM, "unbalanced call to enableFreezer, ignoring");
+ mFreezerDisableCount = 0;
+ return false;
+ }
+ } else {
+ mFreezerDisableCount++;
+
+ if (mFreezerDisableCount > 1) {
+ return true;
+ }
+ }
+
+ try {
+ enableFreezerInternal(enable);
+ return true;
+ } catch (java.lang.RuntimeException e) {
+ if (enable) {
+ mFreezerDisableCount = 0;
+ } else {
+ mFreezerDisableCount = 1;
+ }
+
+ Slog.e(TAG_AM, "Exception handling freezer state (enable: " + enable + "): "
+ + e.toString());
+ }
+
+ return false;
+ }
+
+ /**
+ * Enable or disable the freezer. When enable == false all frozen processes are unfrozen,
+ * but aren't removed from the freezer. While in this state, processes can be added or removed
+ * by using Process.setProcessFrozen(), but they wouldn't be actually frozen until the freezer
+ * is enabled. If enable == true all processes in the freezer are frozen.
+ *
+ * @param enable Specify whether to enable (true) or disable (false) the freezer.
+ *
+ * @hide
+ */
+ private static native void enableFreezerInternal(boolean enable);
+
+ /**
+ * Determines whether the freezer is supported by this system
*/
public static boolean isFreezerSupported() {
boolean supported = false;
FileReader fr = null;
try {
- fr = new FileReader("/dev/freezer/frozen/freezer.killable");
- int i = fr.read();
+ fr = new FileReader("/sys/fs/cgroup/freezer/cgroup.freeze");
+ char state = (char) fr.read();
- if ((char) i == '1') {
+ if (state == '1' || state == '0') {
supported = true;
} else {
- Slog.w(TAG_AM, "Freezer killability is turned off, disabling freezer");
+ Slog.e(TAG_AM, "unexpected value in cgroup.freeze");
}
} catch (java.io.FileNotFoundException e) {
- Slog.d(TAG_AM, "Freezer.killable not present, disabling freezer");
+ Slog.d(TAG_AM, "cgroup.freeze not present");
} catch (Exception e) {
- Slog.d(TAG_AM, "Unable to read freezer.killable, disabling freezer: " + e.toString());
+ Slog.d(TAG_AM, "unable to read cgroup.freeze: " + e.toString());
}
if (fr != null) {
@@ -471,6 +530,8 @@
if (mUseFreezer && mFreezeHandler == null) {
Slog.d(TAG_AM, "Freezer enabled");
+ enableFreezer(true);
+
if (!mCachedAppOptimizerThread.isAlive()) {
mCachedAppOptimizerThread.start();
}
@@ -479,6 +540,8 @@
Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
Process.THREAD_GROUP_SYSTEM);
+ } else {
+ enableFreezer(false);
}
}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 8527ae9..88ecac2 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -116,6 +116,10 @@
WidgetFlags.KEY_ENABLE_CURSOR_DRAG_FROM_ANYWHERE, boolean.class,
WidgetFlags.ENABLE_CURSOR_DRAG_FROM_ANYWHERE_DEFAULT));
sDeviceConfigEntries.add(new DeviceConfigEntry<Integer>(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL,
+ WidgetFlags.KEY_CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL, int.class,
+ WidgetFlags.CURSOR_DRAG_MIN_ANGLE_FROM_VERTICAL_DEFAULT));
+ sDeviceConfigEntries.add(new DeviceConfigEntry<Integer>(
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.FINGER_TO_CURSOR_DISTANCE,
WidgetFlags.KEY_FINGER_TO_CURSOR_DISTANCE, int.class,
WidgetFlags.FINGER_TO_CURSOR_DISTANCE_DEFAULT));
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 828ac71..19d5a31 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -104,6 +104,7 @@
boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
boolean delayed; // are we waiting to start this service in the background?
boolean fgRequired; // is the service required to go foreground after starting?
+ boolean hideFgNotification; // Hide the fg service notification
boolean fgWaiting; // is a timeout for going foreground already scheduled?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
@@ -823,6 +824,9 @@
}
public void postNotification() {
+ if (hideFgNotification) {
+ return;
+ }
final int appUid = appInfo.uid;
final int appPid = app.pid;
if (foregroundId != 0 && foregroundNoti != null) {
@@ -915,7 +919,7 @@
}
if (localForegroundNoti.getSmallIcon() == null) {
// Notifications whose icon is 0 are defined to not show
- // a notification, silently ignoring it. We don't want to
+ // a notification. We don't want to
// just ignore it, we want to prevent the service from
// being foreground.
throw new RuntimeException("invalid service notification: "
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1f85d10..1c93d4e 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -48,6 +48,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkManagementEventObserver;
import android.net.Ikev2VpnProfile;
import android.net.IpPrefix;
@@ -79,6 +80,7 @@
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.INetworkManagementService;
@@ -123,6 +125,7 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
@@ -134,6 +137,8 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -190,6 +195,7 @@
// automated reconnection
private final Context mContext;
+ @VisibleForTesting final Dependencies mDeps;
private final NetworkInfo mNetworkInfo;
@VisibleForTesting protected String mPackage;
private int mOwnerUID;
@@ -252,17 +258,143 @@
// Handle of the user initiating VPN.
private final int mUserHandle;
+ interface RetryScheduler {
+ void checkInterruptAndDelay(boolean sleepLonger) throws InterruptedException;
+ }
+
+ static class Dependencies {
+ public void startService(final String serviceName) {
+ SystemService.start(serviceName);
+ }
+
+ public void stopService(final String serviceName) {
+ SystemService.stop(serviceName);
+ }
+
+ public boolean isServiceRunning(final String serviceName) {
+ return SystemService.isRunning(serviceName);
+ }
+
+ public boolean isServiceStopped(final String serviceName) {
+ return SystemService.isStopped(serviceName);
+ }
+
+ public File getStateFile() {
+ return new File("/data/misc/vpn/state");
+ }
+
+ public void sendArgumentsToDaemon(
+ final String daemon, final LocalSocket socket, final String[] arguments,
+ final RetryScheduler retryScheduler) throws IOException, InterruptedException {
+ final LocalSocketAddress address = new LocalSocketAddress(
+ daemon, LocalSocketAddress.Namespace.RESERVED);
+
+ // Wait for the socket to connect.
+ while (true) {
+ try {
+ socket.connect(address);
+ break;
+ } catch (Exception e) {
+ // ignore
+ }
+ retryScheduler.checkInterruptAndDelay(true /* sleepLonger */);
+ }
+ socket.setSoTimeout(500);
+
+ final OutputStream out = socket.getOutputStream();
+ for (String argument : arguments) {
+ byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
+ if (bytes.length >= 0xFFFF) {
+ throw new IllegalArgumentException("Argument is too large");
+ }
+ out.write(bytes.length >> 8);
+ out.write(bytes.length);
+ out.write(bytes);
+ retryScheduler.checkInterruptAndDelay(false /* sleepLonger */);
+ }
+ out.write(0xFF);
+ out.write(0xFF);
+
+ // Wait for End-of-File.
+ final InputStream in = socket.getInputStream();
+ while (true) {
+ try {
+ if (in.read() == -1) {
+ break;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ retryScheduler.checkInterruptAndDelay(true /* sleepLonger */);
+ }
+ }
+
+ @NonNull
+ public InetAddress resolve(final String endpoint)
+ throws ExecutionException, InterruptedException {
+ try {
+ return InetAddress.parseNumericAddress(endpoint);
+ } catch (IllegalArgumentException e) {
+ // Endpoint is not numeric : fall through and resolve
+ }
+
+ final CancellationSignal cancellationSignal = new CancellationSignal();
+ try {
+ final DnsResolver resolver = DnsResolver.getInstance();
+ final CompletableFuture<InetAddress> result = new CompletableFuture();
+ final DnsResolver.Callback<List<InetAddress>> cb =
+ new DnsResolver.Callback<List<InetAddress>>() {
+ @Override
+ public void onAnswer(@NonNull final List<InetAddress> answer,
+ final int rcode) {
+ if (answer.size() > 0) {
+ result.complete(answer.get(0));
+ } else {
+ result.completeExceptionally(
+ new UnknownHostException(endpoint));
+ }
+ }
+
+ @Override
+ public void onError(@Nullable final DnsResolver.DnsException error) {
+ // Unfortunately UnknownHostException doesn't accept a cause, so
+ // print a message here instead. Only show the summary, not the
+ // full stack trace.
+ Log.e(TAG, "Async dns resolver error : " + error);
+ result.completeExceptionally(new UnknownHostException(endpoint));
+ }
+ };
+ resolver.query(null /* network, null for default */, endpoint,
+ DnsResolver.FLAG_EMPTY, r -> r.run(), cancellationSignal, cb);
+ return result.get();
+ } catch (final ExecutionException e) {
+ Log.e(TAG, "Cannot resolve VPN endpoint : " + endpoint + ".", e);
+ throw e;
+ } catch (final InterruptedException e) {
+ Log.e(TAG, "Legacy VPN was interrupted while resolving the endpoint", e);
+ cancellationSignal.cancel();
+ throw e;
+ }
+ }
+
+ public boolean checkInterfacePresent(final Vpn vpn, final String iface) {
+ return vpn.jniCheck(iface) == 0;
+ }
+ }
+
public Vpn(Looper looper, Context context, INetworkManagementService netService,
@UserIdInt int userHandle, @NonNull KeyStore keyStore) {
- this(looper, context, netService, userHandle, keyStore,
+ this(looper, context, new Dependencies(), netService, userHandle, keyStore,
new SystemServices(context), new Ikev2SessionCreator());
}
@VisibleForTesting
- protected Vpn(Looper looper, Context context, INetworkManagementService netService,
+ protected Vpn(Looper looper, Context context, Dependencies deps,
+ INetworkManagementService netService,
int userHandle, @NonNull KeyStore keyStore, SystemServices systemServices,
Ikev2SessionCreator ikev2SessionCreator) {
mContext = context;
+ mDeps = deps;
mNetd = netService;
mUserHandle = userHandle;
mLooper = looper;
@@ -2129,7 +2261,8 @@
}
/** This class represents the common interface for all VPN runners. */
- private abstract class VpnRunner extends Thread {
+ @VisibleForTesting
+ abstract class VpnRunner extends Thread {
protected VpnRunner(String name) {
super(name);
@@ -2638,7 +2771,7 @@
} catch (InterruptedException e) {
}
for (String daemon : mDaemons) {
- SystemService.stop(daemon);
+ mDeps.stopService(daemon);
}
}
agentDisconnect();
@@ -2655,21 +2788,55 @@
}
}
+ private void checkAndFixupArguments(@NonNull final InetAddress endpointAddress) {
+ final String endpointAddressString = endpointAddress.getHostAddress();
+ // Perform some safety checks before inserting the address in place.
+ // Position 0 in mDaemons and mArguments must be racoon, and position 1 must be mtpd.
+ if (!"racoon".equals(mDaemons[0]) || !"mtpd".equals(mDaemons[1])) {
+ throw new IllegalStateException("Unexpected daemons order");
+ }
+
+ // Respectively, the positions at which racoon and mtpd take the server address
+ // argument are 1 and 2. Not all types of VPN require both daemons however, and
+ // in that case the corresponding argument array is null.
+ if (mArguments[0] != null) {
+ if (!mProfile.server.equals(mArguments[0][1])) {
+ throw new IllegalStateException("Invalid server argument for racoon");
+ }
+ mArguments[0][1] = endpointAddressString;
+ }
+
+ if (mArguments[1] != null) {
+ if (!mProfile.server.equals(mArguments[1][2])) {
+ throw new IllegalStateException("Invalid server argument for mtpd");
+ }
+ mArguments[1][2] = endpointAddressString;
+ }
+ }
+
private void bringup() {
// Catch all exceptions so we can clean up a few things.
try {
+ // resolve never returns null. If it does because of some bug, it will be
+ // caught by the catch() block below and cleanup gracefully.
+ final InetAddress endpointAddress = mDeps.resolve(mProfile.server);
+
+ // Big hack : dynamically replace the address of the server in the arguments
+ // with the resolved address.
+ checkAndFixupArguments(endpointAddress);
+
// Initialize the timer.
mBringupStartTime = SystemClock.elapsedRealtime();
// Wait for the daemons to stop.
for (String daemon : mDaemons) {
- while (!SystemService.isStopped(daemon)) {
+ while (!mDeps.isServiceStopped(daemon)) {
checkInterruptAndDelay(true);
}
}
// Clear the previous state.
- File state = new File("/data/misc/vpn/state");
+ final File state = mDeps.getStateFile();
state.delete();
if (state.exists()) {
throw new IllegalStateException("Cannot delete the state");
@@ -2696,57 +2863,19 @@
// Start the daemon.
String daemon = mDaemons[i];
- SystemService.start(daemon);
+ mDeps.startService(daemon);
// Wait for the daemon to start.
- while (!SystemService.isRunning(daemon)) {
+ while (!mDeps.isServiceRunning(daemon)) {
checkInterruptAndDelay(true);
}
// Create the control socket.
mSockets[i] = new LocalSocket();
- LocalSocketAddress address = new LocalSocketAddress(
- daemon, LocalSocketAddress.Namespace.RESERVED);
- // Wait for the socket to connect.
- while (true) {
- try {
- mSockets[i].connect(address);
- break;
- } catch (Exception e) {
- // ignore
- }
- checkInterruptAndDelay(true);
- }
- mSockets[i].setSoTimeout(500);
-
- // Send over the arguments.
- OutputStream out = mSockets[i].getOutputStream();
- for (String argument : arguments) {
- byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
- if (bytes.length >= 0xFFFF) {
- throw new IllegalArgumentException("Argument is too large");
- }
- out.write(bytes.length >> 8);
- out.write(bytes.length);
- out.write(bytes);
- checkInterruptAndDelay(false);
- }
- out.write(0xFF);
- out.write(0xFF);
-
- // Wait for End-of-File.
- InputStream in = mSockets[i].getInputStream();
- while (true) {
- try {
- if (in.read() == -1) {
- break;
- }
- } catch (Exception e) {
- // ignore
- }
- checkInterruptAndDelay(true);
- }
+ // Wait for the socket to connect and send over the arguments.
+ mDeps.sendArgumentsToDaemon(daemon, mSockets[i], arguments,
+ this::checkInterruptAndDelay);
}
// Wait for the daemons to create the new state.
@@ -2754,7 +2883,7 @@
// Check if a running daemon is dead.
for (int i = 0; i < mDaemons.length; ++i) {
String daemon = mDaemons[i];
- if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
+ if (mArguments[i] != null && !mDeps.isServiceRunning(daemon)) {
throw new IllegalStateException(daemon + " is dead");
}
}
@@ -2764,7 +2893,8 @@
// Now we are connected. Read and parse the new state.
String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
if (parameters.length != 7) {
- throw new IllegalStateException("Cannot parse the state");
+ throw new IllegalStateException("Cannot parse the state: '"
+ + String.join("', '", parameters) + "'");
}
// Set the interface and the addresses in the config.
@@ -2793,20 +2923,15 @@
}
// Add a throw route for the VPN server endpoint, if one was specified.
- String endpoint = parameters[5].isEmpty() ? mProfile.server : parameters[5];
- if (!endpoint.isEmpty()) {
- try {
- InetAddress addr = InetAddress.parseNumericAddress(endpoint);
- if (addr instanceof Inet4Address) {
- mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW));
- } else if (addr instanceof Inet6Address) {
- mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW));
- } else {
- Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint);
- }
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e);
- }
+ if (endpointAddress instanceof Inet4Address) {
+ mConfig.routes.add(new RouteInfo(
+ new IpPrefix(endpointAddress, 32), RTN_THROW));
+ } else if (endpointAddress instanceof Inet6Address) {
+ mConfig.routes.add(new RouteInfo(
+ new IpPrefix(endpointAddress, 128), RTN_THROW));
+ } else {
+ Log.e(TAG, "Unknown IP address family for VPN endpoint: "
+ + endpointAddress);
}
// Here is the last step and it must be done synchronously.
@@ -2818,7 +2943,7 @@
checkInterruptAndDelay(false);
// Check if the interface is gone while we are waiting.
- if (jniCheck(mConfig.interfaze) == 0) {
+ if (mDeps.checkInterfacePresent(Vpn.this, mConfig.interfaze)) {
throw new IllegalStateException(mConfig.interfaze + " is gone");
}
@@ -2849,7 +2974,7 @@
while (true) {
Thread.sleep(2000);
for (int i = 0; i < mDaemons.length; i++) {
- if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) {
+ if (mArguments[i] != null && mDeps.isServiceStopped(mDaemons[i])) {
return;
}
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 041bedc..ec12a97 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -210,6 +210,7 @@
private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm";
private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock";
+ private static final boolean USE_WTF_FOR_ACCOUNT_ERROR = false;
private static final int SYNC_OP_STATE_VALID = 0;
// "1" used to include errors 3, 4 and 5 but now it's split up.
@@ -3446,7 +3447,7 @@
if (isLoggable) {
Slog.v(TAG, " Dropping sync operation: account doesn't exist.");
}
- Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: account doesn't exist.");
+ logAccountError("SYNC_OP_STATE_INVALID: account doesn't exist.");
return SYNC_OP_STATE_INVALID_NO_ACCOUNT;
}
// Drop this sync request if it isn't syncable.
@@ -3456,14 +3457,14 @@
Slog.v(TAG, " Dropping sync operation: "
+ "isSyncable == SYNCABLE_NO_ACCOUNT_ACCESS");
}
- Slog.wtf(TAG, "SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS");
+ logAccountError("SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS");
return SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS;
}
if (state == AuthorityInfo.NOT_SYNCABLE) {
if (isLoggable) {
Slog.v(TAG, " Dropping sync operation: isSyncable == NOT_SYNCABLE");
}
- Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: NOT_SYNCABLE");
+ logAccountError("SYNC_OP_STATE_INVALID: NOT_SYNCABLE");
return SYNC_OP_STATE_INVALID_NOT_SYNCABLE;
}
@@ -3482,12 +3483,20 @@
if (isLoggable) {
Slog.v(TAG, " Dropping sync operation: disallowed by settings/network.");
}
- Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: disallowed by settings/network");
+ logAccountError("SYNC_OP_STATE_INVALID: disallowed by settings/network");
return SYNC_OP_STATE_INVALID_SYNC_DISABLED;
}
return SYNC_OP_STATE_VALID;
}
+ private void logAccountError(String message) {
+ if (USE_WTF_FOR_ACCOUNT_ERROR) {
+ Slog.wtf(TAG, message);
+ } else {
+ Slog.e(TAG, message);
+ }
+ }
+
private boolean dispatchSyncOperation(SyncOperation op) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Slog.v(TAG, "dispatchSyncOperation: we are going to sync " + op);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1058000..24661d6 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2548,8 +2548,7 @@
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mSyncRoot) {
- return mDisplayPowerController.requestPowerState(request,
- waitForNegativeProximity);
+ return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity);
}
}
@@ -2677,6 +2676,10 @@
return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp);
}
+ @Override
+ public void ignoreProximitySensorUntilChanged() {
+ mDisplayPowerController.ignoreProximitySensorUntilChanged();
+ }
}
class DesiredDisplayModeSpecsObserver
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 9411c562..7c0f419 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -117,6 +117,7 @@
private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
+ private static final int MSG_IGNORE_PROXIMITY = 8;
private static final int PROXIMITY_UNKNOWN = -1;
private static final int PROXIMITY_NEGATIVE = 0;
@@ -263,6 +264,11 @@
// go to sleep by the user. While true, the screen remains off.
private boolean mWaitingForNegativeProximity;
+ // True if the device should not take into account the proximity sensor
+ // until either the proximity sensor state changes, or there is no longer a
+ // request to listen to proximity sensor.
+ private boolean mIgnoreProximityUntilChanged;
+
// The actual proximity sensor threshold value.
private float mProximityThreshold;
@@ -760,8 +766,7 @@
if (mPowerRequest == null) {
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
- mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
- mPendingWaitForNegativeProximityLocked = false;
+ updatePendingProximityRequestsLocked();
mPendingRequestChangedLocked = false;
mustInitialize = true;
// Assume we're on and bright until told otherwise, since that's the state we turn
@@ -770,8 +775,7 @@
} else if (mPendingRequestChangedLocked) {
previousPolicy = mPowerRequest.policy;
mPowerRequest.copyFrom(mPendingRequestLocked);
- mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
- mPendingWaitForNegativeProximityLocked = false;
+ updatePendingProximityRequestsLocked();
mPendingRequestChangedLocked = false;
mDisplayReadyLocked = false;
} else {
@@ -822,9 +826,16 @@
// Apply the proximity sensor.
if (mProximitySensor != null) {
if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
+ // At this point the policy says that the screen should be on, but we've been
+ // asked to listen to the prox sensor to adjust the display state, so lets make
+ // sure the sensor is on.
setProximitySensorEnabled(true);
if (!mScreenOffBecauseOfProximity
- && mProximity == PROXIMITY_POSITIVE) {
+ && mProximity == PROXIMITY_POSITIVE
+ && !mIgnoreProximityUntilChanged) {
+ // Prox sensor already reporting "near" so we should turn off the screen.
+ // Also checked that we aren't currently set to ignore the proximity sensor
+ // temporarily.
mScreenOffBecauseOfProximity = true;
sendOnProximityPositiveWithWakelock();
}
@@ -832,18 +843,28 @@
&& mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE
&& state != Display.STATE_OFF) {
+ // The policy says that we should have the screen on, but it's off due to the prox
+ // and we've been asked to wait until the screen is far from the user to turn it
+ // back on. Let keep the prox sensor on so we can tell when it's far again.
setProximitySensorEnabled(true);
} else {
+ // We haven't been asked to use the prox sensor and we're not waiting on the screen
+ // to turn back on...so lets shut down the prox sensor.
setProximitySensorEnabled(false);
mWaitingForNegativeProximity = false;
}
+
if (mScreenOffBecauseOfProximity
- && mProximity != PROXIMITY_POSITIVE) {
+ && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
+ // The screen *was* off due to prox being near, but now it's "far" so lets turn
+ // the screen back on. Also turn it back on if we've been asked to ignore the
+ // prox sensor temporarily.
mScreenOffBecauseOfProximity = false;
sendOnProximityNegativeWithWakelock();
}
} else {
mWaitingForNegativeProximity = false;
+ mIgnoreProximityUntilChanged = false;
}
if (mScreenOffBecauseOfProximity) {
state = Display.STATE_OFF;
@@ -1181,6 +1202,14 @@
sendUpdatePowerState();
}
+ /**
+ * Ignores the proximity sensor until the sensor state changes, but only if the sensor is
+ * currently enabled and forcing the screen to be dark.
+ */
+ public void ignoreProximitySensorUntilChanged() {
+ mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
+ }
+
public void setBrightnessConfiguration(BrightnessConfiguration c) {
Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
msg.sendToTarget();
@@ -1529,6 +1558,7 @@
// Register the listener.
// Proximity sensor state already cleared initially.
mProximitySensorEnabled = true;
+ mIgnoreProximityUntilChanged = false;
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
}
@@ -1538,6 +1568,7 @@
// Clear the proximity sensor state for next time.
mProximitySensorEnabled = false;
mProximity = PROXIMITY_UNKNOWN;
+ mIgnoreProximityUntilChanged = false;
mPendingProximity = PROXIMITY_UNKNOWN;
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
mSensorManager.unregisterListener(mProximitySensorListener);
@@ -1580,6 +1611,11 @@
&& mPendingProximityDebounceTime >= 0) {
final long now = SystemClock.uptimeMillis();
if (mPendingProximityDebounceTime <= now) {
+ if (mProximity != mPendingProximity) {
+ // if the status of the sensor changed, stop ignoring.
+ mIgnoreProximityUntilChanged = false;
+ Slog.i(TAG, "No longer ignoring proximity [" + mPendingProximity + "]");
+ }
// Sensor reading accepted. Apply the change then release the wake lock.
mProximity = mPendingProximity;
updatePowerState();
@@ -1723,6 +1759,27 @@
}
}
+ private void updatePendingProximityRequestsLocked() {
+ mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
+ mPendingWaitForNegativeProximityLocked = false;
+
+ if (mIgnoreProximityUntilChanged) {
+ // Also, lets stop waiting for negative proximity if we're ignoring it.
+ mWaitingForNegativeProximity = false;
+ }
+ }
+
+ private void ignoreProximitySensorUntilChangedInternal() {
+ if (!mIgnoreProximityUntilChanged
+ && mPowerRequest.useProximitySensor
+ && mProximity == PROXIMITY_POSITIVE) {
+ // Only ignore if it is still reporting positive (near)
+ mIgnoreProximityUntilChanged = true;
+ Slog.i(TAG, "Ignoring proximity");
+ updatePowerState();
+ }
+ }
+
private final Runnable mOnStateChangedRunnable = new Runnable() {
@Override
public void run() {
@@ -1961,6 +2018,10 @@
mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
updatePowerState();
break;
+
+ case MSG_IGNORE_PROXIMITY:
+ ignoreProximitySensorUntilChangedInternal();
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index bfcbe46..9adde24 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -1586,6 +1586,7 @@
}
record.mRequest = locationRequest;
+ record.mReceiver.updateMonitoring(true);
requests.add(locationRequest);
if (!locationRequest.isLowPowerMode()) {
providerRequest.setLowPowerMode(false);
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 3a4dfaf..0b3cdae 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -34,6 +34,7 @@
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaRoute2Info;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -55,7 +56,6 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
- private static BluetoothRouteProvider sInstance;
@SuppressWarnings("WeakerAccess") /* synthetic access */
// Maps hardware address to BluetoothRouteInfo
@@ -79,19 +79,21 @@
private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener();
- static synchronized BluetoothRouteProvider getInstance(@NonNull Context context,
+ /**
+ * Create an instance of {@link BluetoothRouteProvider}.
+ * It may return {@code null} if Bluetooth is not supported on this hardware platform.
+ */
+ @Nullable
+ static BluetoothRouteProvider createInstance(@NonNull Context context,
@NonNull BluetoothRoutesUpdatedListener listener) {
Objects.requireNonNull(context);
Objects.requireNonNull(listener);
- if (sInstance == null) {
- BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
- if (btAdapter == null) {
- return null;
- }
- sInstance = new BluetoothRouteProvider(context, btAdapter, listener);
+ BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (btAdapter == null) {
+ return null;
}
- return sInstance;
+ return new BluetoothRouteProvider(context, btAdapter, listener);
}
private BluetoothRouteProvider(Context context, BluetoothAdapter btAdapter,
@@ -103,7 +105,7 @@
buildBluetoothRoutes();
}
- public void start() {
+ public void start(UserHandle user) {
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
@@ -118,7 +120,8 @@
addEventReceiver(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED,
deviceStateChangedReceiver);
- mContext.registerReceiver(mBroadcastReceiver, mIntentFilter, null, null);
+ mContext.registerReceiverAsUser(mBroadcastReceiver, user,
+ mIntentFilter, null, null);
}
/**
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 875bfdf..1114fe0 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -1176,7 +1176,8 @@
super(Looper.getMainLooper(), null, true);
mServiceRef = new WeakReference<>(service);
mUserRecord = userRecord;
- mSystemProvider = new SystemMediaRoute2Provider(service.mContext);
+ mSystemProvider = new SystemMediaRoute2Provider(service.mContext,
+ UserHandle.of(userRecord.mUserId));
mRouteProviders.add(mSystemProvider);
mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
this, mUserRecord.mUserId);
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 2c089ca..4f7af94 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -45,6 +45,7 @@
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -99,7 +100,7 @@
}
};
- SystemMediaRoute2Provider(Context context) {
+ SystemMediaRoute2Provider(Context context, UserHandle user) {
super(sComponentName);
mIsSystemRouteProvider = true;
@@ -117,7 +118,7 @@
updateDeviceRoute(newAudioRoutes);
// .getInstance returns null if there is no bt adapter available
- mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> {
+ mBtRouteProvider = BluetoothRouteProvider.createInstance(context, (routes) -> {
publishProviderState();
boolean sessionInfoChanged;
@@ -130,11 +131,12 @@
IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
- mContext.registerReceiver(new AudioManagerBroadcastReceiver(), intentFilter);
+ mContext.registerReceiverAsUser(new AudioManagerBroadcastReceiver(), user,
+ intentFilter, null, null);
if (mBtRouteProvider != null) {
mHandler.post(() -> {
- mBtRouteProvider.start();
+ mBtRouteProvider.start(user);
notifyProviderState();
});
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
index cb1c7e4..1c79332 100644
--- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -99,11 +99,16 @@
if (match != null) continue;
// Create listener for every newly added sub. Also store subscriberId into it to
- // prevent binder call to telephony when querying RAT.
+ // prevent binder call to telephony when querying RAT. If the subscriberId is empty
+ // for any reason, such as SIM PIN locked, skip registration.
+ // SubscriberId will be unavailable again if 1. modem crashed 2. reboot
+ // 3. re-insert SIM. If that happens, the listeners will be eventually synchronized
+ // with active sub list once all subscriberIds are ready.
final String subscriberId = mTeleManager.getSubscriberId(subId);
if (TextUtils.isEmpty(subscriberId)) {
- Log.wtf(NetworkStatsService.TAG,
- "Empty subscriberId for newly added sub: " + subId);
+ Log.d(NetworkStatsService.TAG, "Empty subscriberId for newly added sub "
+ + subId + ", skip listener registration");
+ continue;
}
final RatTypeListener listener =
new RatTypeListener(mExecutor, this, subId, subscriberId);
@@ -112,6 +117,7 @@
// Register listener to the telephony manager that associated with specific sub.
mTeleManager.createForSubscriptionId(subId)
.listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE);
+ Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + subId);
}
for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
@@ -164,6 +170,7 @@
private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) {
mTeleManager.createForSubscriptionId(listener.mSubId)
.listen(listener, PhoneStateListener.LISTEN_NONE);
+ Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId);
mRatListeners.remove(listener);
// Removal of subscriptions doesn't generate RAT changed event, fire it for every
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8dc7b93..f8d54ad 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7733,6 +7733,13 @@
@VisibleForTesting
void updateUriPermissions(@Nullable NotificationRecord newRecord,
@Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId) {
+ updateUriPermissions(newRecord, oldRecord, targetPkg, targetUserId, false);
+ }
+
+ @VisibleForTesting
+ void updateUriPermissions(@Nullable NotificationRecord newRecord,
+ @Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId,
+ boolean onlyRevokeCurrentTarget) {
final String key = (newRecord != null) ? newRecord.getKey() : oldRecord.getKey();
if (DBG) Slog.d(TAG, key + ": updating permissions");
@@ -7760,7 +7767,9 @@
}
// If we have no Uris to grant, but an existing owner, go destroy it
- if (newUris == null && permissionOwner != null) {
+ // When revoking permissions of a single listener, destroying the owner will revoke
+ // permissions of other listeners who need to keep access.
+ if (newUris == null && permissionOwner != null && !onlyRevokeCurrentTarget) {
destroyPermissionOwner(permissionOwner, UserHandle.getUserId(oldRecord.getUid()), key);
permissionOwner = null;
}
@@ -7783,9 +7792,20 @@
final Uri uri = oldUris.valueAt(i);
if (newUris == null || !newUris.contains(uri)) {
if (DBG) Slog.d(TAG, key + ": revoking " + uri);
- int userId = ContentProvider.getUserIdFromUri(
- uri, UserHandle.getUserId(oldRecord.getUid()));
- revokeUriPermission(permissionOwner, uri, userId);
+ if (onlyRevokeCurrentTarget) {
+ // We're revoking permission from one listener only; other listeners may
+ // still need access because the notification may still exist
+ revokeUriPermission(permissionOwner, uri,
+ UserHandle.getUserId(oldRecord.getUid()), targetPkg, targetUserId);
+ } else {
+ // This is broad to unilaterally revoke permissions to this Uri as granted
+ // by this notification. But this code-path can only be used when the
+ // reason for revoking is that the notification posted again without this
+ // Uri, not when removing an individual listener.
+ revokeUriPermission(permissionOwner, uri,
+ UserHandle.getUserId(oldRecord.getUid()),
+ null, UserHandle.USER_ALL);
+ }
}
}
}
@@ -7814,8 +7834,10 @@
}
}
- private void revokeUriPermission(IBinder owner, Uri uri, int userId) {
+ private void revokeUriPermission(IBinder owner, Uri uri, int sourceUserId, String targetPkg,
+ int targetUserId) {
if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
+ int userId = ContentProvider.getUserIdFromUri(uri, sourceUserId);
final long ident = Binder.clearCallingIdentity();
try {
@@ -7823,7 +7845,7 @@
owner,
ContentProvider.getUriWithoutUserId(uri),
Intent.FLAG_GRANT_READ_URI_PERMISSION,
- userId);
+ userId, targetPkg, targetUserId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -9191,6 +9213,7 @@
final NotificationRankingUpdate update;
synchronized (mNotificationLock) {
update = makeRankingUpdateLocked(info);
+ updateUriPermissionsForActiveNotificationsLocked(info, true);
}
try {
listener.onListenerConnected(update);
@@ -9202,6 +9225,7 @@
@Override
@GuardedBy("mNotificationLock")
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
+ updateUriPermissionsForActiveNotificationsLocked(removed, false);
if (removeDisabledHints(removed)) {
updateListenerHintsLocked();
updateEffectsSuppressorLocked();
@@ -9268,8 +9292,7 @@
for (final ManagedServiceInfo info : getServices()) {
boolean sbnVisible = isVisibleToListener(sbn, info);
- boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info)
- : false;
+ boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, info);
// This notification hasn't been and still isn't visible -> ignore.
if (!oldSbnVisible && !sbnVisible) {
continue;
@@ -9293,13 +9316,8 @@
// This notification became invisible -> remove the old one.
if (oldSbnVisible && !sbnVisible) {
final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyRemoved(
- info, oldSbnLightClone, update, null, REASON_USER_STOPPED);
- }
- });
+ mHandler.post(() -> notifyRemoved(
+ info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
continue;
}
@@ -9309,12 +9327,7 @@
updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
final StatusBarNotification sbnToPost = trimCache.ForListener(info);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyPosted(info, sbnToPost, update);
- }
- });
+ mHandler.post(() -> notifyPosted(info, sbnToPost, update));
}
} catch (Exception e) {
Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e);
@@ -9322,6 +9335,46 @@
}
/**
+ * Synchronously grant or revoke permissions to Uris for all active and visible
+ * notifications to just the NotificationListenerService provided.
+ */
+ @GuardedBy("mNotificationLock")
+ private void updateUriPermissionsForActiveNotificationsLocked(
+ ManagedServiceInfo info, boolean grant) {
+ try {
+ for (final NotificationRecord r : mNotificationList) {
+ // When granting permissions, ignore notifications which are invisible.
+ // When revoking permissions, all notifications are invisible, so process all.
+ if (grant && !isVisibleToListener(r.getSbn(), info)) {
+ continue;
+ }
+ // If the notification is hidden, permissions are not required by the listener.
+ if (r.isHidden() && info.targetSdkVersion < Build.VERSION_CODES.P) {
+ continue;
+ }
+ // Grant or revoke access synchronously
+ final int targetUserId = (info.userid == UserHandle.USER_ALL)
+ ? UserHandle.USER_SYSTEM : info.userid;
+ if (grant) {
+ // Grant permissions by passing arguments as if the notification is new.
+ updateUriPermissions(/* newRecord */ r, /* oldRecord */ null,
+ info.component.getPackageName(), targetUserId);
+ } else {
+ // Revoke permissions by passing arguments as if the notification was
+ // removed, but set `onlyRevokeCurrentTarget` to avoid revoking permissions
+ // granted to *other* targets by this notification's URIs.
+ updateUriPermissions(/* newRecord */ null, /* oldRecord */ r,
+ info.component.getPackageName(), targetUserId,
+ /* onlyRevokeCurrentTarget */ true);
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Could not " + (grant ? "grant" : "revoke") + " Uri permissions to "
+ + info.component, e);
+ }
+ }
+
+ /**
* asynchronously notify all listeners about a removed notification
*/
@GuardedBy("mNotificationLock")
@@ -9356,18 +9409,11 @@
final NotificationStats stats = mAssistants.isServiceTokenValidLocked(info.service)
? notificationStats : null;
final NotificationRankingUpdate update = makeRankingUpdateLocked(info);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyRemoved(info, sbnLight, update, stats, reason);
- }
- });
+ mHandler.post(() -> notifyRemoved(info, sbnLight, update, stats, reason));
}
// Revoke access after all listeners have been updated
- mHandler.post(() -> {
- updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM);
- });
+ mHandler.post(() -> updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM));
}
/**
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index bc78d66..c3cb42f 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -75,6 +75,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -173,6 +174,8 @@
private boolean mAllowInvalidShortcuts = false;
+ private Map<String, List<String>> mOemLockedApps = new HashMap();
+
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager,
@@ -314,6 +317,12 @@
}
channel.setImportanceLockedByCriticalDeviceFunction(
r.defaultAppLockedImportance);
+ channel.setImportanceLockedByOEM(r.oemLockedImportance);
+ if (!channel.isImportanceLockedByOEM()) {
+ if (r.oemLockedChannels.contains(channel.getId())) {
+ channel.setImportanceLockedByOEM(true);
+ }
+ }
boolean isInvalidShortcutChannel =
channel.getConversationId() != null &&
channel.getConversationId().contains(
@@ -396,6 +405,14 @@
r.visibility = visibility;
r.showBadge = showBadge;
r.bubblePreference = bubblePreference;
+ if (mOemLockedApps.containsKey(r.pkg)) {
+ List<String> channels = mOemLockedApps.get(r.pkg);
+ if (channels == null || channels.isEmpty()) {
+ r.oemLockedImportance = true;
+ } else {
+ r.oemLockedChannels = channels;
+ }
+ }
try {
createDefaultChannelIfNeededLocked(r);
@@ -1149,8 +1166,10 @@
String channelId = appSplit.length == 2 ? appSplit[1] : null;
synchronized (mPackagePreferences) {
+ boolean foundApp = false;
for (PackagePreferences r : mPackagePreferences.values()) {
if (r.pkg.equals(appName)) {
+ foundApp = true;
if (channelId == null) {
// lock all channels for the app
r.oemLockedImportance = true;
@@ -1168,6 +1187,14 @@
}
}
}
+ if (!foundApp) {
+ List<String> channels =
+ mOemLockedApps.getOrDefault(appName, new ArrayList<>());
+ if (channelId != null) {
+ channels.add(channelId);
+ }
+ mOemLockedApps.put(appName, channels);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 994cec2..ea53132 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -267,6 +267,9 @@
/** Uid of the creator of this session. */
private final int mOriginalInstallerUid;
+ /** Package name of the app that created the installation session. */
+ private final String mOriginalInstallerPackageName;
+
/** Uid of the owner of the installer session */
@GuardedBy("mLock")
private int mInstallerUid;
@@ -556,6 +559,7 @@
mOriginalInstallerUid = installerUid;
mInstallerUid = installerUid;
mInstallSource = Objects.requireNonNull(installSource);
+ mOriginalInstallerPackageName = mInstallSource.installerPackageName;
this.params = params;
this.createdMillis = createdMillis;
this.updatedMillis = createdMillis;
@@ -1666,11 +1670,6 @@
throw new IllegalArgumentException("Package is not valid", e);
}
- if (!mPackageName.equals(mInstallSource.installerPackageName)) {
- throw new SecurityException("Can only transfer sessions that update the original "
- + "installer");
- }
-
mInstallerUid = newOwnerAppInfo.uid;
mInstallSource = InstallSource.create(packageName, null, packageName);
}
@@ -2157,6 +2156,15 @@
}
}
+ if (mInstallerUid != mOriginalInstallerUid) {
+ // Session has been transferred, check package name.
+ if (TextUtils.isEmpty(mPackageName) || !mPackageName.equals(
+ mOriginalInstallerPackageName)) {
+ throw new PackageManagerException(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED,
+ "Can only transfer sessions that update the original installer");
+ }
+ }
+
if (params.mode == SessionParams.MODE_FULL_INSTALL) {
// Full installs must include a base package
if (!stagedSplits.contains(null)) {
@@ -3182,6 +3190,7 @@
pw.printPair("userId", userId);
pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid);
+ pw.printPair("mOriginalInstallerPackageName", mOriginalInstallerPackageName);
pw.printPair("installerPackageName", mInstallSource.installerPackageName);
pw.printPair("installInitiatingPackageName", mInstallSource.initiatingPackageName);
pw.printPair("installOriginatingPackageName", mInstallSource.originatingPackageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4eae0da..150fdaa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2376,9 +2376,12 @@
final int callingUserId = UserHandle.getUserId(callingUid);
for (String packageName : packages) {
- PackageSetting setting = mSettings.mPackages.get(packageName);
- if (setting != null
- && !shouldFilterApplicationLocked(setting, callingUid, callingUserId)) {
+ final boolean filterApp;
+ synchronized (mLock) {
+ final PackageSetting ps = mSettings.getPackageLPr(packageName);
+ filterApp = shouldFilterApplicationLocked(ps, callingUid, callingUserId);
+ }
+ if (!filterApp) {
notifyInstallObserver(packageName);
}
}
@@ -8914,10 +8917,10 @@
if (providerInfo == null) {
return null;
}
- if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
- return null;
- }
synchronized (mLock) {
+ if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
+ return null;
+ }
final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
final ComponentName component =
new ComponentName(providerInfo.packageName, providerInfo.name);
@@ -9004,9 +9007,11 @@
String targetPackage, int flags) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final PackageSetting ps = mSettings.mPackages.get(targetPackage);
- if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
- return ParceledListSlice.emptyList();
+ synchronized (mLock) {
+ final PackageSetting ps = mSettings.getPackageLPr(targetPackage);
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
+ return ParceledListSlice.emptyList();
+ }
}
return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags,
callingUserId));
@@ -14501,7 +14506,7 @@
final PackageSetting ps;
int appId = -1;
long ceDataInode = -1;
- synchronized (mSettings) {
+ synchronized (mLock) {
ps = mSettings.getPackageLPr(packageName);
if (ps != null) {
appId = ps.appId;
@@ -19356,9 +19361,11 @@
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */, "clear application data");
- final PackageSetting ps = mSettings.getPackageLPr(packageName);
- final boolean filterApp =
- (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
+ final boolean filterApp;
+ synchronized (mLock) {
+ final PackageSetting ps = mSettings.getPackageLPr(packageName);
+ filterApp = shouldFilterApplicationLocked(ps, callingUid, userId);
+ }
if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
throw new SecurityException("Cannot clear data for a protected package: "
+ packageName);
@@ -19638,11 +19645,13 @@
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
- if (getUidTargetSdkVersionLockedLPr(callingUid)
- < Build.VERSION_CODES.FROYO) {
- Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
- + callingUid);
- return;
+ synchronized (mLock) {
+ if (getUidTargetSdkVersionLockedLPr(callingUid)
+ < Build.VERSION_CODES.FROYO) {
+ Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+ + callingUid);
+ return;
+ }
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
@@ -19814,8 +19823,9 @@
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
private void clearPackagePreferredActivities(String packageName, int userId) {
final SparseBooleanArray changedUsers = new SparseBooleanArray();
-
- clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
+ synchronized (mLock) {
+ clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
+ }
if (changedUsers.size() > 0) {
updateDefaultHomeNotLocked(changedUsers);
postPreferredActivityChangedBroadcast(userId);
@@ -19937,7 +19947,9 @@
// writer
try {
final SparseBooleanArray changedUsers = new SparseBooleanArray();
- clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
+ synchronized (mLock) {
+ clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
+ }
if (changedUsers.size() > 0) {
postPreferredActivityChangedBroadcast(userId);
}
@@ -20942,15 +20954,19 @@
// Limit who can change which apps
if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
// Don't allow apps that don't have permission to modify other apps
- if (!allowedByPermission
- || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
+ final boolean filterApp;
+ synchronized (mLock) {
+ filterApp = (!allowedByPermission
+ || shouldFilterApplicationLocked(pkgSetting, callingUid, userId));
+ }
+ if (filterApp) {
throw new SecurityException(
"Attempt to change component state; "
- + "pid=" + Binder.getCallingPid()
- + ", uid=" + callingUid
- + (className == null
+ + "pid=" + Binder.getCallingPid()
+ + ", uid=" + callingUid
+ + (className == null
? ", package=" + packageName
- : ", component=" + packageName + "/" + className));
+ : ", component=" + packageName + "/" + className));
}
// Don't allow changing protected packages.
if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
@@ -25289,18 +25305,7 @@
int mode = mInjector.getAppOpsManager().checkOpNoThrow(
AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
Binder.getCallingUid(), packageName);
- if (mode == MODE_ALLOWED) {
- return false;
- } else if (mode == MODE_IGNORED) {
- return true;
- } else {
- synchronized (mLock) {
- boolean manifestWhitelisted =
- mPackages.get(packageName).getAutoRevokePermissions()
- == ApplicationInfo.AUTO_REVOKE_DISALLOWED;
- return manifestWhitelisted;
- }
- }
+ return mode == MODE_IGNORED;
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index bc7554c..a4e8b1c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -83,6 +83,7 @@
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.permission.SplitPermissionInfoParcelable;
@@ -120,6 +121,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.TimingsTraceLog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -2516,12 +2518,12 @@
final PermissionsState permissionsState = ps.getPermissionsState();
- final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
+ final int[] userIds = getAllUserIds();
boolean runtimePermissionsRevoked = false;
int[] updatedUserIds = EMPTY_INT_ARRAY;
- for (int userId : currentUserIds) {
+ for (int userId : userIds) {
if (permissionsState.isMissing(userId)) {
Collection<String> requestedPermissions;
int targetSdkVersion;
@@ -2587,7 +2589,7 @@
// runtime and revocation of a runtime from a shared user.
synchronized (mLock) {
updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
- ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
+ ps.getSharedUser(), userIds);
if (!ArrayUtils.isEmpty(updatedUserIds)) {
runtimePermissionsRevoked = true;
}
@@ -2740,7 +2742,7 @@
// a runtime permission being downgraded to an install one.
// Also in permission review mode we keep dangerous permissions
// for legacy apps
- for (int userId : UserManagerService.getInstance().getUserIds()) {
+ for (int userId : userIds) {
if (origPermissions.getRuntimePermissionState(
perm, userId) != null) {
// Revoke the runtime permission and clear the flags.
@@ -2763,7 +2765,7 @@
boolean hardRestricted = bp.isHardRestricted();
boolean softRestricted = bp.isSoftRestricted();
- for (int userId : currentUserIds) {
+ for (int userId : userIds) {
// If permission policy is not ready we don't deal with restricted
// permissions as the policy may whitelist some permissions. Once
// the policy is initialized we would re-evaluate permissions.
@@ -2902,7 +2904,7 @@
boolean hardRestricted = bp.isHardRestricted();
boolean softRestricted = bp.isSoftRestricted();
- for (int userId : currentUserIds) {
+ for (int userId : userIds) {
// If permission policy is not ready we don't deal with restricted
// permissions as the policy may whitelist some permissions. Once
// the policy is initialized we would re-evaluate permissions.
@@ -3071,6 +3073,25 @@
}
/**
+ * Returns all relevant user ids. This list include the current set of created user ids as well
+ * as pre-created user ids.
+ * @return user ids for created users and pre-created users
+ */
+ private int[] getAllUserIds() {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("getAllUserIds");
+ List<UserInfo> users = UserManagerService.getInstance().getUsers(
+ /*excludePartial=*/ true, /*excludeDying=*/ true, /*excludePreCreated=*/ false);
+ int size = users.size();
+ final int[] userIds = new int[size];
+ for (int i = 0; i < size; i++) {
+ userIds[i] = users.get(i).id;
+ }
+ t.traceEnd();
+ return userIds;
+ }
+
+ /**
* Revoke permissions that are not implicit anymore and that have
* {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
*
@@ -3088,7 +3109,7 @@
boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
>= Build.VERSION_CODES.M;
- int[] users = UserManagerService.getInstance().getUserIds();
+ int[] users = getAllUserIds();
int numUsers = users.length;
for (int i = 0; i < numUsers; i++) {
int userId = users[i];
@@ -3197,7 +3218,7 @@
if (replace && pkg.isRequestLegacyExternalStorage() && (
pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
|| pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
- return UserManagerService.getInstance().getUserIds();
+ return getAllUserIds();
}
return updatedUserIds;
@@ -3251,7 +3272,7 @@
if (!ps.hasInstallPermission(newPerm)) {
BasePermission bp = mSettings.getPermissionLocked(newPerm);
- int[] users = UserManagerService.getInstance().getUserIds();
+ int[] users = getAllUserIds();
int numUsers = users.length;
for (int userNum = 0; userNum < numUsers; userNum++) {
int userId = users[userNum];
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 37f088b..9dd9236 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -88,7 +88,7 @@
public final class PermissionPolicyService extends SystemService {
private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 10000;
+ private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 60000;
private final Object mLock = new Object();
@@ -282,6 +282,11 @@
manager.updateUserSensitiveForApp(uid);
}
}, UserHandle.ALL, intentFilter, null, null);
+
+ PermissionControllerManager manager = new PermissionControllerManager(
+ getUserContext(getContext(), Process.myUserHandle()), FgThread.getHandler());
+ FgThread.getHandler().postDelayed(manager::updateUserSensitive,
+ USER_SENSITIVE_UPDATE_DELAY_MS);
}
/**
@@ -420,8 +425,7 @@
throw new IllegalStateException(e);
}
- FgThread.getHandler().postDelayed(permissionControllerManager::updateUserSensitive,
- USER_SENSITIVE_UPDATE_DELAY_MS);
+ permissionControllerManager.updateUserSensitive();
packageManagerInternal.updateRuntimePermissionsFingerprint(userId);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dadc990..3faf3be 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -933,6 +933,8 @@
}
}
+ final boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event);
+
GestureLauncherService gestureService = LocalServices.getService(
GestureLauncherService.class);
boolean gesturedServiceIntercepted = false;
@@ -952,7 +954,8 @@
// If the power key has still not yet been handled, then detect short
// press, long press, or multi press and decide what to do.
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
- || mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
+ || mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted
+ || handledByPowerManager;
if (!mPowerKeyHandled) {
if (interactive) {
// When interactive, we're already awake.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 764ac96..f965e58 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -85,6 +85,7 @@
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import android.view.KeyEvent;
import com.android.internal.BrightnessSynchronizer;
import com.android.internal.annotations.VisibleForTesting;
@@ -5425,6 +5426,29 @@
}
}
+ /**
+ * If the user presses power while the proximity sensor is enabled and keeping
+ * the screen off, then turn the screen back on by telling display manager to
+ * ignore the proximity sensor. We don't turn off the proximity sensor because
+ * we still want it to be reenabled if it's state changes.
+ *
+ * @return True if the proximity sensor was successfully ignored and we should
+ * consume the key event.
+ */
+ private boolean interceptPowerKeyDownInternal(KeyEvent event) {
+ synchronized (mLock) {
+ // DisplayPowerController only reports proximity positive (near) if it's
+ // positive and the proximity wasn't already being ignored. So it reliably
+ // also tells us that we're not already ignoring the proximity sensor.
+ if (mDisplayPowerRequest.useProximitySensor && mProximityPositive) {
+ mDisplayManagerInternal.ignoreProximitySensorUntilChanged();
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@VisibleForTesting
final class LocalService extends PowerManagerInternal {
@Override
@@ -5561,5 +5585,10 @@
public WakeData getLastWakeup() {
return getLastWakeupInternal();
}
+
+ @Override
+ public boolean interceptPowerKeyDown(KeyEvent event) {
+ return interceptPowerKeyDownInternal(event);
+ }
}
}
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index 37df548..0d059ae 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -338,11 +338,12 @@
}
/**
- * Returns {@code true} if {@code vol} is an emulated or public volume,
+ * Returns {@code true} if {@code vol} is an emulated or visible public volume,
* {@code false} otherwise
**/
public static boolean isEmulatedOrPublic(VolumeInfo vol) {
- return vol.type == VolumeInfo.TYPE_EMULATED || vol.type == VolumeInfo.TYPE_PUBLIC;
+ return vol.type == VolumeInfo.TYPE_EMULATED
+ || (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isVisible());
}
/** Exception thrown when communication with the {@link ExternalStorageService} fails. */
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
index cdb6199..5772dea 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
@@ -75,10 +75,31 @@
void removeUriPermissionsForPackage(
String packageName, int userHandle, boolean persistable, boolean targetOnly);
/**
- * @param uri This uri must NOT contain an embedded userId.
+ * Remove any {@link UriPermission} associated with the owner whose values match the given
+ * filtering parameters.
+ *
+ * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}.
+ * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris.
+ * @param mode The modes (as a bitmask) to revoke.
* @param userId The userId in which the uri is to be resolved.
*/
void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId);
+
+ /**
+ * Remove any {@link UriPermission} associated with the owner whose values match the given
+ * filtering parameters.
+ *
+ * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}.
+ * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris.
+ * @param mode The modes (as a bitmask) to revoke.
+ * @param userId The userId in which the uri is to be resolved.
+ * @param targetPkg Calling package name to match, or {@code null} to apply to all packages.
+ * @param targetUserId Calling user to match, or {@link UserHandle#USER_ALL} to apply to all
+ * users.
+ */
+ void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId,
+ String targetPkg, int targetUserId);
+
boolean checkAuthorityGrants(
int callingUid, ProviderInfo cpi, int userId, boolean checkUser);
void dump(PrintWriter pw, boolean dumpAll, String dumpPackage);
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index f14c3a5..8eefd8f 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -51,7 +51,6 @@
import android.app.GrantedUriPermission;
import android.app.IUriGrantsManager;
import android.content.ClipData;
-import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
@@ -88,11 +87,11 @@
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
-import libcore.io.IoUtils;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -1431,16 +1430,18 @@
@Override
public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
+ revokeUriPermissionFromOwner(token, uri, mode, userId, null, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId,
+ String targetPkg, int targetUserId) {
final UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
if (owner == null) {
throw new IllegalArgumentException("Unknown owner: " + token);
}
-
- if (uri == null) {
- owner.removeUriPermissions(mode);
- } else {
- owner.removeUriPermission(new GrantUri(userId, uri, mode), mode);
- }
+ GrantUri grantUri = uri == null ? null : new GrantUri(userId, uri, mode);
+ owner.removeUriPermission(grantUri, mode, targetPkg, targetUserId);
}
@Override
diff --git a/services/core/java/com/android/server/uri/UriPermissionOwner.java b/services/core/java/com/android/server/uri/UriPermissionOwner.java
index 2b404a4..0c26399 100644
--- a/services/core/java/com/android/server/uri/UriPermissionOwner.java
+++ b/services/core/java/com/android/server/uri/UriPermissionOwner.java
@@ -21,6 +21,7 @@
import android.os.Binder;
import android.os.IBinder;
+import android.os.UserHandle;
import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
@@ -74,30 +75,47 @@
}
void removeUriPermission(GrantUri grantUri, int mode) {
+ removeUriPermission(grantUri, mode, null, UserHandle.USER_ALL);
+ }
+
+ void removeUriPermission(GrantUri grantUri, int mode, String targetPgk, int targetUserId) {
if ((mode & FLAG_GRANT_READ_URI_PERMISSION) != 0 && mReadPerms != null) {
Iterator<UriPermission> it = mReadPerms.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
- if (grantUri == null || grantUri.equals(perm.uri)) {
- perm.removeReadOwner(this);
- mService.removeUriPermissionIfNeeded(perm);
- it.remove();
+ if (grantUri != null && !grantUri.equals(perm.uri)) {
+ continue;
}
+ if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+ continue;
+ }
+ if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+ continue;
+ }
+ perm.removeReadOwner(this);
+ mService.removeUriPermissionIfNeeded(perm);
+ it.remove();
}
if (mReadPerms.isEmpty()) {
mReadPerms = null;
}
}
- if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0
- && mWritePerms != null) {
+ if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 && mWritePerms != null) {
Iterator<UriPermission> it = mWritePerms.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
- if (grantUri == null || grantUri.equals(perm.uri)) {
- perm.removeWriteOwner(this);
- mService.removeUriPermissionIfNeeded(perm);
- it.remove();
+ if (grantUri != null && !grantUri.equals(perm.uri)) {
+ continue;
}
+ if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+ continue;
+ }
+ if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+ continue;
+ }
+ perm.removeWriteOwner(this);
+ mService.removeUriPermissionIfNeeded(perm);
+ it.remove();
}
if (mWritePerms.isEmpty()) {
mWritePerms = null;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3e9377e..5339d86 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1671,7 +1671,8 @@
static int getLockTaskLaunchMode(ActivityInfo aInfo, @Nullable ActivityOptions options) {
int lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
- if (aInfo.applicationInfo.isPrivilegedApp()
+ // Non-priv apps are not allowed to use always or never, fall back to default
+ if (!aInfo.applicationInfo.isPrivilegedApp()
&& (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
|| lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
@@ -2543,7 +2544,9 @@
final ActivityStack stack = getRootTask();
final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null)
- && stack.isFocusedStackOnDisplay();
+ && stack.isFocusedStackOnDisplay()
+ // Do not adjust focus task because the task will be reused to launch new activity.
+ && !task.isClearingToReuseTask();
final boolean shouldAdjustGlobalFocus = mayAdjustTop
// It must be checked before {@link #makeFinishingLocked} is called, because a stack
// is not visible if it only contains finishing activities.
@@ -4578,15 +4581,6 @@
return false;
}
- // Check if the activity is on a sleeping display, and if it can turn it ON.
- if (getDisplay().isSleeping()) {
- final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn()
- || canShowWhenLocked() || containsDismissKeyguardWindow();
- if (!canTurnScreenOn) {
- return false;
- }
- }
-
// Now check whether it's really visible depending on Keyguard state, and update
// {@link ActivityStack} internal states.
// Inform the method if this activity is the top activity of this stack, but exclude the
@@ -4597,6 +4591,12 @@
final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
+ // Check if the activity is on a sleeping display, and if it can turn it ON.
+ // TODO(b/163993448): Do not make activity visible before display awake.
+ if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) {
+ return !mSetToSleep || canTurnScreenOn();
+ }
+
return visibleIgnoringDisplayStatus;
}
@@ -4735,6 +4735,15 @@
Slog.v(TAG_VISIBILITY, "Start visible activity, " + this);
}
setState(STARTED, "makeActiveIfNeeded");
+
+ // Update process info while making an activity from invisible to visible, to make
+ // sure the process state is updated to foreground.
+ if (app != null) {
+ app.updateProcessInfo(false /* updateServiceConnectionActivities */,
+ true /* activityChange */, true /* updateOomAdj */,
+ true /* addPendingTopUid */);
+ }
+
try {
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
StartActivityItem.obtain());
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index cf1d59f..cd508d0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -146,7 +146,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -2723,13 +2722,15 @@
/**
* Reset local parameters because an app's activity died.
* @param app The app of the activity that died.
- * @return result from removeHistoryRecordsForAppLocked.
+ * @return {@code true} if the process has any visible activity.
*/
boolean handleAppDied(WindowProcessController app) {
+ boolean isPausingDied = false;
if (mPausingActivity != null && mPausingActivity.app == app) {
if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
"App died while pausing: " + mPausingActivity);
mPausingActivity = null;
+ isPausingDied = true;
}
if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
mLastPausedActivity = null;
@@ -2737,7 +2738,8 @@
}
mStackSupervisor.removeHistoryRecords(app);
- return mRemoveHistoryRecordsForApp.process(app);
+ final boolean hadVisibleActivities = mRemoveHistoryRecordsForApp.process(app);
+ return hadVisibleActivities || isPausingDied;
}
boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
@@ -3040,8 +3042,6 @@
getDisplayArea().positionStackAtTop(this, false /* includingParents */);
mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
- MetricsLoggerWrapper.logPictureInPictureFullScreen(mAtmService.mContext,
- task.effectiveUid, task.realActivity.flattenToString());
});
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index b378621..b869eb5 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2009,8 +2009,6 @@
// of history or if it is finished immediately), thus disassociating the task. Also note
// that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
// launching another activity.
- // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
- // already launching one.
targetTask.performClearTaskLocked();
targetTask.setIntent(mStartActivity);
mAddingToTask = true;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index a1d0e56..52d4b6f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -183,7 +183,6 @@
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
-import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -239,12 +238,9 @@
import com.android.internal.app.AssistUtils;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.ProcessMap;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.TransferPipe;
-import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.ArrayUtils;
@@ -3001,13 +2997,7 @@
@Override
public void stopLockTaskModeByToken(IBinder token) {
- synchronized (mGlobalLock) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r == null) {
- return;
- }
- stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
- }
+ stopLockTaskModeInternal(token, false /* isSystemCaller */);
}
/**
@@ -3049,11 +3039,19 @@
}
}
- private void stopLockTaskModeInternal(@Nullable Task task, boolean isSystemCaller) {
+ private void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) {
final int callingUid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
+ Task task = null;
+ if (token != null) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ return;
+ }
+ task = r.getTask();
+ }
getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
}
// Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
@@ -4109,10 +4107,6 @@
final ActivityStack stack = r.getRootTask();
stack.setPictureInPictureAspectRatio(aspectRatio);
stack.setPictureInPictureActions(actions);
- MetricsLoggerWrapper.logPictureInPictureEnter(mContext,
- r.info.applicationInfo.uid, r.shortComponentName,
- r.supportsEnterPipOnTaskSwitch);
- logPictureInPictureArgs(params);
}
};
@@ -4156,7 +4150,6 @@
r.pictureInPictureArgs.getAspectRatio());
stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
}
- logPictureInPictureArgs(params);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -4170,18 +4163,6 @@
return 3;
}
- private void logPictureInPictureArgs(PictureInPictureParams params) {
- if (params.hasSetActions()) {
- MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
- params.getActions().size());
- }
- if (params.hasSetAspectRatio()) {
- LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
- lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
- MetricsLogger.action(lm);
- }
- }
-
/**
* Checks the state of the system and the activity associated with the given {@param token} to
* verify that picture-in-picture is supported for that activity.
@@ -5380,15 +5361,6 @@
return mAmInternal.isBackgroundActivityStartsEnabled();
}
- void enableScreenAfterBoot(boolean booted) {
- writeBootProgressEnableScreen(SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();
-
- synchronized (mGlobalLock) {
- updateEventDispatchingLocked(booted);
- }
- }
-
static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
if (r == null || !r.hasProcess()) {
return KEY_DISPATCHING_TIMEOUT_MS;
@@ -6474,9 +6446,9 @@
@Override
public void enableScreenAfterBoot(boolean booted) {
+ writeBootProgressEnableScreen(SystemClock.uptimeMillis());
+ mWindowManager.enableScreenAfterBoot();
synchronized (mGlobalLock) {
- writeBootProgressEnableScreen(SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();
updateEventDispatchingLocked(booted);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fcbc756..0363ea0 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1573,7 +1573,12 @@
// the heavy operations. This also benefits that the states of multiple activities
// are handled together.
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
- setFixedRotationLaunchingAppUnchecked(r, rotation);
+ if (r != mFixedRotationTransitionListener.mAnimatingRecents) {
+ // Only update the record for normal activity so the display orientation can be
+ // updated when the transition is done if it becomes the top. And the case of
+ // recents can be handled when the recents animation is finished.
+ setFixedRotationLaunchingAppUnchecked(r, rotation);
+ }
return;
}
@@ -5642,6 +5647,9 @@
*/
private ActivityRecord mAnimatingRecents;
+ /** Whether {@link #mAnimatingRecents} is going to be the top activity. */
+ private boolean mRecentsWillBeTop;
+
/**
* If the recents activity has a fixed orientation which is different from the current top
* activity, it will be rotated before being shown so we avoid a screen rotation animation
@@ -5667,10 +5675,12 @@
* If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we
* don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition.
*/
- void onFinishRecentsAnimation(boolean moveRecentsToBack) {
+ void onFinishRecentsAnimation() {
final ActivityRecord animatingRecents = mAnimatingRecents;
+ final boolean recentsWillBeTop = mRecentsWillBeTop;
mAnimatingRecents = null;
- if (!moveRecentsToBack) {
+ mRecentsWillBeTop = false;
+ if (recentsWillBeTop) {
// The recents activity will be the top, such as staying at recents list or
// returning to home (if home and recents are the same activity).
return;
@@ -5693,6 +5703,10 @@
}
}
+ void notifyRecentsWillBeTop() {
+ mRecentsWillBeTop = true;
+ }
+
/**
* Return {@code true} if there is an ongoing animation to the "Recents" activity and this
* activity as a fixed orientation so shouldn't be rotated.
@@ -5713,6 +5727,14 @@
if (r == null || r == mAnimatingRecents) {
return;
}
+ if (mAnimatingRecents != null && mRecentsWillBeTop) {
+ // The activity is not the recents and it should be moved to back later, so it is
+ // better to keep its current appearance for the next transition. Otherwise the
+ // display orientation may be updated too early and the layout procedures at the
+ // end of finishing recents animation is skipped. That causes flickering because
+ // the surface of closing app hasn't updated to invisible.
+ return;
+ }
if (mFixedRotationLaunchingApp == null) {
// In most cases this is a no-op if the activity doesn't have fixed rotation.
// Otherwise it could be from finishing recents animation while the display has
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 6a90f29..5c5ec35 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -246,6 +246,9 @@
| View.STATUS_BAR_TRANSPARENT
| View.NAVIGATION_BAR_TRANSPARENT;
+ private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR};
+ private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR};
+
private final WindowManagerService mService;
private final Context mContext;
private final Context mUiContext;
@@ -3330,8 +3333,15 @@
return;
}
+ final InsetsState requestedState = controlTarget.getRequestedInsetsState();
+ final @InsetsType int restorePositionTypes =
+ (requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR)
+ ? Type.navigationBars() : 0)
+ | (requestedState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR)
+ ? Type.statusBars() : 0);
+
if (swipeTarget == mNavigationBar
- && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
+ && (restorePositionTypes & Type.navigationBars()) != 0) {
// Don't show status bar when swiping on already visible navigation bar.
// But restore the position of navigation bar if it has been moved by the control
// target.
@@ -3339,14 +3349,13 @@
return;
}
- int insetsTypesToShow = Type.systemBars();
-
if (controlTarget.canShowTransient()) {
- insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
- new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
- }
- if (insetsTypesToShow != 0) {
- controlTarget.showInsets(insetsTypesToShow, false);
+ // Show transient bars if they are hidden; restore position if they are visible.
+ mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_SWIPE);
+ controlTarget.showInsets(restorePositionTypes, false);
+ } else {
+ // Restore visibilities and positions of system bars.
+ controlTarget.showInsets(Type.statusBars() | Type.navigationBars(), false);
}
} else {
boolean sb = mStatusBarController.checkShowTransientBarLw();
@@ -3923,8 +3932,7 @@
mPendingPanicGestureUptime = SystemClock.uptimeMillis();
if (!isNavBarEmpty(mLastSystemUiFlags)) {
mNavigationBarController.showTransient();
- mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
- new int[] {ITYPE_NAVIGATION_BAR}));
+ mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_PANIC);
}
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index 3ffc26a..5e7ed3f 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import android.inputmethodservice.InputMethodService;
+import android.view.InsetsState;
import android.view.WindowInsets.Type.InsetsType;
/**
@@ -38,6 +39,13 @@
}
/**
+ * @return The requested {@link InsetsState} of this target.
+ */
+ default InsetsState getRequestedInsetsState() {
+ return InsetsState.EMPTY;
+ }
+
+ /**
* Instructs the control target to show inset sources.
*
* @param types to specify which types of insets source window should be shown.
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 82e7555..fd67db1 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -42,7 +42,6 @@
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.ViewRootImpl;
-import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.WindowInsetsAnimationControlListener;
@@ -154,15 +153,13 @@
return provider != null && provider.hasWindow() && !provider.getSource().isVisible();
}
- @InsetsType int showTransient(IntArray types) {
- @InsetsType int showingTransientTypes = 0;
+ void showTransient(@InternalInsetsType int[] types) {
boolean changed = false;
- for (int i = types.size() - 1; i >= 0; i--) {
- final int type = types.get(i);
+ for (int i = types.length - 1; i >= 0; i--) {
+ final @InternalInsetsType int type = types[i];
if (!isHidden(type)) {
continue;
}
- showingTransientTypes |= InsetsState.toPublicType(type);
if (mShowingTransientTypes.indexOf(type) != -1) {
continue;
}
@@ -190,7 +187,6 @@
}
});
}
- return showingTransientTypes;
}
void hideTransient() {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index a2b295a..65db23c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -702,6 +702,11 @@
"cleanupAnimation(): Notify animation finished mPendingAnimations=%d "
+ "reorderMode=%d",
mPendingAnimations.size(), reorderMode);
+ if (reorderMode != REORDER_MOVE_TO_ORIGINAL_POSITION) {
+ // Notify the state at the beginning because the removeAnimation may notify the
+ // transition is finished. This is a signal that there will be a next transition.
+ mDisplayContent.mFixedRotationTransitionListener.notifyRecentsWillBeTop();
+ }
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
@@ -742,8 +747,7 @@
mTargetActivityRecord.token);
}
}
- mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(
- reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */);
+ mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
// Notify that the animation has ended
if (mStatusBar != null) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6785127..954b7a0 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1528,14 +1528,25 @@
*/
void performClearTaskLocked() {
mReuseTask = true;
- performClearTask("clear-task-all");
- mReuseTask = false;
+ mStackSupervisor.beginDeferResume();
+ try {
+ performClearTask("clear-task-all");
+ } finally {
+ mStackSupervisor.endDeferResume();
+ mReuseTask = false;
+ }
}
ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
mReuseTask = true;
- final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
- mReuseTask = false;
+ mStackSupervisor.beginDeferResume();
+ final ActivityRecord result;
+ try {
+ result = performClearTaskLocked(newR, launchFlags);
+ } finally {
+ mStackSupervisor.endDeferResume();
+ mReuseTask = false;
+ }
return result;
}
@@ -2371,8 +2382,16 @@
// For calculating screen layout, we need to use the non-decor inset screen area for the
// calculation for compatibility reasons, i.e. screen area without system bars that
// could never go away in Honeycomb.
- final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
- final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
+ int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
+ int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
+ // Use overrides if provided. If both overrides are provided, mTmpNonDecorBounds is
+ // undefined so it can't be used.
+ if (inOutConfig.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
+ compatScreenWidthDp = inOutConfig.screenWidthDp;
+ }
+ if (inOutConfig.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
+ compatScreenHeightDp = inOutConfig.screenHeightDp;
+ }
// Reducing the screen layout starting from its parent config.
inOutConfig.screenLayout = computeScreenLayoutOverride(parentConfig.screenLayout,
compatScreenWidthDp, compatScreenHeightDp);
@@ -3608,6 +3627,9 @@
info.topActivityInfo = mReuseActivitiesReport.top != null
? mReuseActivitiesReport.top.info
: null;
+ info.requestedOrientation = mReuseActivitiesReport.base != null
+ ? mReuseActivitiesReport.base.getRequestedOrientation()
+ : SCREEN_ORIENTATION_UNSET;
}
/**
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index f70bf18..e153bef 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -458,7 +458,8 @@
|| mTmpTaskInfo.topActivityType != lastInfo.topActivityType
|| mTmpTaskInfo.isResizeable != lastInfo.isResizeable
|| mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams
- || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription);
+ || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription)
+ || mTmpTaskInfo.requestedOrientation != lastInfo.requestedOrientation;
if (!changed) {
int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 29cf177..bd959ab 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -188,7 +188,6 @@
private final Configuration mLastReportedConfiguration = new Configuration();
// Configuration that is waiting to be dispatched to the process.
private Configuration mPendingConfiguration;
- private final Configuration mNewOverrideConfig = new Configuration();
// Registered display id as a listener to override config change
private int mDisplayId;
private ActivityRecord mConfigActivityRecord;
@@ -1168,11 +1167,26 @@
}
@Override
+ public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
+ super.onRequestedOverrideConfigurationChanged(
+ sanitizeProcessConfiguration(overrideConfiguration));
+ }
+
+ @Override
public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
+ super.onRequestedOverrideConfigurationChanged(
+ sanitizeProcessConfiguration(mergedOverrideConfig));
+ }
+
+ private static Configuration sanitizeProcessConfiguration(Configuration config) {
// Make sure that we don't accidentally override the activity type.
- mNewOverrideConfig.setTo(mergedOverrideConfig);
- mNewOverrideConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
- super.onRequestedOverrideConfigurationChanged(mNewOverrideConfig);
+ if (config.windowConfiguration.getActivityType() != ACTIVITY_TYPE_UNDEFINED) {
+ final Configuration sanitizedConfig = new Configuration(config);
+ sanitizedConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+ return sanitizedConfig;
+ }
+
+ return config;
}
private void updateConfiguration() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 11db705..3b8928e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -725,7 +725,8 @@
* @return The insets state as requested by the client, i.e. the dispatched insets state
* for which the visibilities are overridden with what the client requested.
*/
- InsetsState getRequestedInsetsState() {
+ @Override
+ public InsetsState getRequestedInsetsState() {
return mRequestedInsetsState;
}
@@ -2051,10 +2052,17 @@
// animating... let's do something.
final int left = mWindowFrames.mFrame.left;
final int top = mWindowFrames.mFrame.top;
+
+ // During the transition from pip to fullscreen, the activity windowing mode is set to
+ // fullscreen at the beginning while the task is kept in pinned mode. Skip the move
+ // animation in such case since the transition is handled in SysUI.
+ final boolean hasMovementAnimation = getTask() == null
+ ? getWindowConfiguration().hasMovementAnimations()
+ : getTask().getWindowConfiguration().hasMovementAnimations();
if (mToken.okToAnimate()
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
&& !isDragResizing()
- && getWindowConfiguration().hasMovementAnimations()
+ && hasMovementAnimation
&& !mWinAnimator.mLastHidden
&& !mSeamlesslyRotated) {
startMoveAnimation(left, top);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index da45300..80c84ad 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -38,6 +38,7 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
@@ -1478,7 +1479,7 @@
mWin.getDisplayContent().adjustForImeIfNeeded();
}
- return mWin.isAnimating(PARENTS);
+ return mWin.isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 86aacf3..1716dcd 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -531,7 +531,7 @@
void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
Configuration config) {
if (mFixedRotationTransformState != null) {
- return;
+ cleanUpFixedRotationTransformState(true /* replacing */);
}
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
new Configuration(config), mDisplayContent.getRotation());
@@ -548,12 +548,12 @@
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
*/
void linkFixedRotationTransform(WindowToken other) {
- if (mFixedRotationTransformState != null) {
+ final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
+ if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) {
return;
}
- final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
- if (fixedRotationState == null) {
- return;
+ if (mFixedRotationTransformState != null) {
+ cleanUpFixedRotationTransformState(true /* replacing */);
}
mFixedRotationTransformState = fixedRotationState;
fixedRotationState.mAssociatedTokens.add(this);
@@ -609,11 +609,17 @@
// The state is cleared at the end, because it is used to indicate that other windows can
// use seamless rotation when applying rotation to display.
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
- state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState();
+ state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(
+ false /* replacing */);
}
}
- private void cleanUpFixedRotationTransformState() {
+ private void cleanUpFixedRotationTransformState(boolean replacing) {
+ if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) {
+ // The state is not only used by self. Make sure to leave the influence by others.
+ mFixedRotationTransformState.mAssociatedTokens.remove(this);
+ mFixedRotationTransformState.mRotatedContainers.remove(this);
+ }
mFixedRotationTransformState = null;
notifyFixedRotationTransform(false /* enabled */);
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 925ad0f..460842e 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -106,6 +106,7 @@
"libkeystore_binder",
"libmtp",
"libnativehelper",
+ "libprocessgroup",
"libutils",
"libui",
"libinput",
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 6a6da0e..7e9e11d 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -30,6 +30,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>
+#include <processgroup/processgroup.h>
using android::base::StringPrintf;
using android::base::WriteStringToFile;
@@ -74,9 +75,26 @@
}
}
+static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal(
+ JNIEnv *env, jobject clazz, jboolean enable) {
+ bool success = true;
+
+ if (enable) {
+ success = SetTaskProfiles(0, {"FreezerEnabled"}, true);
+ } else {
+ success = SetTaskProfiles(0, {"FreezerDisabled"}, true);
+ }
+
+ if (!success) {
+ jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
+ }
+}
+
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
+ {"enableFreezerInternal", "(Z)V",
+ (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal},
};
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)
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 16aa87b..52e0818 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -3865,7 +3865,7 @@
mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
- eq(message1.getDataUri()), anyInt(), anyInt());
+ eq(message1.getDataUri()), anyInt(), anyInt(), eq(null), eq(-1));
// Update back means we grant access to first again
reset(mUgm);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 2e49929..0d680a2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -2633,6 +2633,96 @@
}
@Test
+ public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet() {
+ mHelper.lockChannelsForOEM(new String[] {PKG_O});
+
+ NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+ NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+ mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
+
+ assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
+ .isImportanceLockedByOEM());
+ assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
+ .isImportanceLockedByOEM());
+ }
+
+ @Test
+ public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet() {
+ mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
+
+ NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+ NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+ NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
+ // different uids, same package
+ mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
+ mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
+
+ assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
+ .isImportanceLockedByOEM());
+ assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
+ .isImportanceLockedByOEM());
+ assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
+ .isImportanceLockedByOEM());
+ }
+
+ @Test
+ public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData()
+ throws Exception {
+ mHelper.lockChannelsForOEM(new String[] {PKG_O});
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+ + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+ + "</package>"
+ + "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1 + "\" >\n"
+ + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+ + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false)
+ .isImportanceLockedByOEM());
+ assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "b", false)
+ .isImportanceLockedByOEM());
+ }
+
+ @Test
+ public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData()
+ throws Exception {
+ mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n"
+ + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+ + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+ + "</package>"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n"
+ + "<channel id=\"c\" name=\"c\" importance=\"3\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false)
+ .isImportanceLockedByOEM());
+ assertTrue(mHelper.getNotificationChannel(PKG_O, 3, "b", false)
+ .isImportanceLockedByOEM());
+ assertTrue(mHelper.getNotificationChannel(PKG_O, 30, "c", false)
+ .isImportanceLockedByOEM());
+ }
+
+ @Test
public void testLockChannelsForOEM_channelSpecific_clearData() {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
mHelper.getImportance(PKG_O, UID_O);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index c7b45ef..1ef0acd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -20,6 +20,10 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -79,6 +83,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
@@ -536,7 +541,7 @@
mActivity = new ActivityBuilder(mService)
.setTask(mTask)
.setLaunchTaskBehind(true)
- .setConfigChanges(CONFIG_ORIENTATION)
+ .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT)
.build();
mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
@@ -1100,6 +1105,34 @@
}
/**
+ * Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping
+ * display.
+ */
+ @Test
+ public void testDisplaySleeping_activityInvisible() {
+ final KeyguardController keyguardController =
+ mActivity.mStackSupervisor.getKeyguardController();
+ doReturn(true).when(keyguardController).isKeyguardLocked();
+ final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ topActivity.mVisibleRequested = true;
+ topActivity.nowVisible = true;
+ topActivity.setState(RESUMED, "test" /*reason*/);
+ doReturn(true).when(topActivity).containsDismissKeyguardWindow();
+ doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
+ any() /* starting */, anyInt() /* configChanges */,
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ topActivity.setShowWhenLocked(true);
+
+ // Verify the top activity is occluded keyguard.
+ assertEquals(topActivity, mStack.topRunningActivity());
+ assertTrue(mStack.topActivityOccludesKeyguard());
+
+ final DisplayContent display = mActivity.mDisplayContent;
+ doReturn(true).when(display).isSleeping();
+ assertFalse(topActivity.shouldBeVisible());
+ }
+
+ /**
* Verify that complete finish request for a show-when-locked activity must ensure the
* keyguard occluded state being updated.
*/
@@ -1657,6 +1690,32 @@
.diff(wpc.getRequestedOverrideConfiguration()));
}
+ @Test
+ public void testGetLockTaskLaunchMode() {
+ final ActivityOptions options = ActivityOptions.makeBasic().setLockTaskEnabled(true);
+ mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
+ assertEquals(LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED,
+ ActivityRecord.getLockTaskLaunchMode(mActivity.info, options));
+
+ mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_ALWAYS;
+ assertEquals(LOCK_TASK_LAUNCH_MODE_DEFAULT,
+ ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/));
+
+ mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_NEVER;
+ assertEquals(LOCK_TASK_LAUNCH_MODE_DEFAULT,
+ ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/));
+
+ mActivity.info.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
+ mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_ALWAYS;
+ assertEquals(LOCK_TASK_LAUNCH_MODE_ALWAYS,
+ ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/));
+
+ mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_NEVER;
+ assertEquals(LOCK_TASK_LAUNCH_MODE_NEVER,
+ ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/));
+
+ }
+
/**
* Creates an activity on display. For non-default display request it will also create a new
* display with custom DisplayInfo.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index f65d6e0..48be58f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -225,5 +225,27 @@
mockSession.finishMocking();
}
+
+ @Test
+ public void testResumeNextActivityOnCrashedAppDied() {
+ mSupervisor.beginDeferResume();
+ final ActivityRecord homeActivity = new ActivityBuilder(mService)
+ .setTask(mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootHomeTask())
+ .build();
+ final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true).build();
+ mSupervisor.endDeferResume();
+ // Assume the activity is finishing and hidden because it was crashed.
+ activity.finishing = true;
+ activity.mVisibleRequested = false;
+ activity.setVisible(false);
+ activity.getRootTask().mPausingActivity = activity;
+ homeActivity.setState(ActivityStack.ActivityState.PAUSED, "test");
+
+ // Even the visibility states are invisible, the next activity should be resumed because
+ // the crashed activity was pausing.
+ mService.mInternal.handleAppDied(activity.app, false /* restarting */,
+ null /* finishInstrumentationCallback */);
+ assertEquals(ActivityStack.ActivityState.RESUMED, homeActivity.getState());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index cbccfb3..dc838f1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1282,7 +1282,7 @@
assertFalse(displayRotation.updateRotationUnchecked(false));
// Rotation can be updated if the recents animation is finished.
- mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false);
+ mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
assertTrue(displayRotation.updateRotationUnchecked(false));
// Rotation can be updated if the recents animation is animating but it is not on top, e.g.
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 87bc7f1..90af8a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -43,7 +43,6 @@
import static org.mockito.Mockito.spy;
import android.platform.test.annotations.Presubmit;
-import android.util.IntArray;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.test.InsetsModeSession;
@@ -241,8 +240,7 @@
}).when(policy).startAnimation(anyBoolean(), any(), any());
policy.updateBarControlTarget(mAppWindow);
- policy.showTransient(
- IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
waitUntilWindowAnimatorIdle();
final InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -269,8 +267,7 @@
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
policy.updateBarControlTarget(mAppWindow);
- policy.showTransient(
- IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
waitUntilWindowAnimatorIdle();
final InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -298,8 +295,7 @@
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
policy.updateBarControlTarget(mAppWindow);
- policy.showTransient(
- IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
waitUntilWindowAnimatorIdle();
InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -337,8 +333,7 @@
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
policy.updateBarControlTarget(app);
- policy.showTransient(
- IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
final InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
policy.updateBarControlTarget(app2);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 8e85e7b..f277117 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -363,12 +363,14 @@
assertFalse(homeActivity.hasFixedRotationTransform());
}
- @Test
- public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
+ private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() {
final ActivityRecord homeActivity = createHomeActivity();
homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ // Add a window so it can be animated by the recents.
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+ activity.addWindow(win);
// Assume an activity is launching to different rotation.
mDefaultDisplay.setFixedRotationLaunchingApp(activity,
(mDefaultDisplay.getRotation() + 1) % 4);
@@ -379,6 +381,14 @@
// Before the transition is done, the recents animation is triggered.
initializeRecentsAnimationController(mController, homeActivity);
assertFalse(homeActivity.hasFixedRotationTransform());
+ assertTrue(mController.isAnimatingTask(activity.getTask()));
+
+ return activity;
+ }
+
+ @Test
+ public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
+ final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();
// Simulate giving up the swipe up gesture to keep the original activity as top.
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
@@ -388,6 +398,21 @@
}
@Test
+ public void testKeepFixedRotationWhenMovingRecentsToTop() {
+ final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();
+ // Assume a transition animation has started running before recents animation. Then the
+ // activity will receive onAnimationFinished that notifies app transition finished when
+ // removing the recents animation of task.
+ activity.getTask().getAnimationSources().add(activity);
+
+ // Simulate swiping to home/recents before the transition is done.
+ mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
+ // The rotation transform should be preserved. In real case, it will be cleared by the next
+ // move-to-top transition.
+ assertTrue(activity.hasFixedRotationTransform());
+ }
+
+ @Test
public void testWallpaperHasFixedRotationApplied() {
mWm.setRecentsAnimationController(mController);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index fb24d86..ddaa586 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -403,6 +403,31 @@
}
@Test
+ public void testComputeConfigResourceLayoutOverrides() {
+ final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500);
+ TestDisplayContent display = new TestDisplayContent.Builder(
+ mService, fullScreenBounds.width(), fullScreenBounds.height()).build();
+ final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+ final Configuration inOutConfig = new Configuration();
+ final Configuration parentConfig = new Configuration();
+ final Rect nonLongBounds = new Rect(0, 0, 1000, 1250);
+ parentConfig.windowConfiguration.setBounds(fullScreenBounds);
+ parentConfig.windowConfiguration.setAppBounds(fullScreenBounds);
+ parentConfig.densityDpi = 400;
+ parentConfig.screenHeightDp = (fullScreenBounds.bottom * 160) / parentConfig.densityDpi;
+ parentConfig.screenWidthDp = (fullScreenBounds.right * 160) / parentConfig.densityDpi;
+ parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+ // Set BOTH screenW/H to an override value
+ inOutConfig.screenWidthDp = nonLongBounds.width() * 160 / parentConfig.densityDpi;
+ inOutConfig.screenHeightDp = nonLongBounds.height() * 160 / parentConfig.densityDpi;
+ task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+ // screenLayout should honor override when both screenW/H are set.
+ assertTrue((inOutConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_NO) != 0);
+ }
+
+ @Test
public void testComputeNestedConfigResourceOverrides() {
final Task task = new TaskBuilder(mSupervisor).build();
assertTrue(task.getResolvedOverrideBounds().isEmpty());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index cdf8eb4..24950ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.INVALID_DISPLAY;
@@ -253,6 +255,19 @@
assertFalse(mWpc.registeredForActivityConfigChanges());
}
+ @Test
+ public void testProcessLevelConfiguration() {
+ Configuration config = new Configuration();
+ config.windowConfiguration.setActivityType(ACTIVITY_TYPE_HOME);
+ mWpc.onRequestedOverrideConfigurationChanged(config);
+ assertEquals(ACTIVITY_TYPE_HOME, config.windowConfiguration.getActivityType());
+ assertEquals(ACTIVITY_TYPE_UNDEFINED, mWpc.getActivityType());
+
+ mWpc.onMergedOverrideConfigurationChanged(config);
+ assertEquals(ACTIVITY_TYPE_HOME, config.windowConfiguration.getActivityType());
+ assertEquals(ACTIVITY_TYPE_UNDEFINED, mWpc.getActivityType());
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mService, 1000, 1500).build();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 23a097e..0896db4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -24,6 +24,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -139,6 +140,8 @@
public void testFinishFixedRotationTransform() {
final WindowToken appToken = mAppWindow.mToken;
final WindowToken wallpaperToken = mWallpaperWindow.mToken;
+ final WindowToken testToken =
+ WindowTestUtils.createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
final int originalRotation = config.windowConfiguration.getRotation();
final int targetRotation = (originalRotation + 1) % 4;
@@ -151,11 +154,20 @@
assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation());
assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation());
- // The display doesn't rotate, the transformation will be canceled.
- mAppWindow.mToken.finishFixedRotationTransform();
+ testToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
+ // The wallpaperToken was linked to appToken, this should make it link to testToken.
+ wallpaperToken.linkFixedRotationTransform(testToken);
- // The window tokens should restore to the original rotation.
+ // Assume the display doesn't rotate, the transformation will be canceled.
+ appToken.finishFixedRotationTransform();
+
+ // The appToken should restore to the original rotation.
assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());
+ // The wallpaperToken is linked to testToken, it should keep the target rotation.
+ assertNotEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
+
+ testToken.finishFixedRotationTransform();
+ // The rotation of wallpaperToken should be restored because its linked state is finished.
assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 52f1e37..5d79775 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1642,6 +1642,15 @@
"hide_lte_plus_data_icon_bool";
/**
+ * The combined channel bandwidth threshold (non-inclusive) in KHz required to display the
+ * LTE+ data icon. It is 20000 by default, meaning the LTE+ icon will be shown if the device is
+ * using carrier aggregation and the combined channel bandwidth is strictly greater than 20 MHz.
+ * @hide
+ */
+ public static final String KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT =
+ "lte_plus_threshold_bandwidth_khz_int";
+
+ /**
* The string is used to filter redundant string from PLMN Network Name that's supplied by
* specific carrier.
*
@@ -4211,6 +4220,7 @@
sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, "");
sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+ sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
sDefaults.putBoolean(KEY_NR_ENABLED_BOOL, true);
sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index e34bbfc..a8206e6 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -37,7 +37,7 @@
private static final String TAG = "CellIdentityNr";
private static final int MAX_PCI = 1007;
- private static final int MAX_TAC = 65535;
+ private static final int MAX_TAC = 16777215; // 0xffffff
private static final int MAX_NRARFCN = 3279165;
private static final long MAX_NCI = 68719476735L;
@@ -50,10 +50,22 @@
// a list of additional PLMN-IDs reported for this cell
private final ArraySet<String> mAdditionalPlmns;
+ /** @hide */
+ public CellIdentityNr() {
+ super(TAG, CellInfo.TYPE_NR, null, null, null, null);
+ mNrArfcn = CellInfo.UNAVAILABLE;
+ mPci = CellInfo.UNAVAILABLE;
+ mTac = CellInfo.UNAVAILABLE;
+ mNci = CellInfo.UNAVAILABLE;
+ mBands = new int[] {};
+ mAdditionalPlmns = new ArraySet();
+ mGlobalCellId = null;
+ }
+
/**
*
* @param pci Physical Cell Id in range [0, 1007].
- * @param tac 16-bit Tracking Area Code.
+ * @param tac 24-bit Tracking Area Code.
* @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165].
* @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2.
* @param mccStr 3-digit Mobile Country Code in string format.
@@ -199,7 +211,7 @@
/**
* Get the tracking area code.
- * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
+ * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
*/
@IntRange(from = 0, to = 65535)
public int getTac() {
diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java
index a7e79f9..e01e8f0 100644
--- a/telephony/java/android/telephony/CellInfoNr.java
+++ b/telephony/java/android/telephony/CellInfoNr.java
@@ -29,9 +29,16 @@
public final class CellInfoNr extends CellInfo {
private static final String TAG = "CellInfoNr";
- private final CellIdentityNr mCellIdentity;
+ private CellIdentityNr mCellIdentity;
private final CellSignalStrengthNr mCellSignalStrength;
+ /** @hide */
+ public CellInfoNr() {
+ super();
+ mCellIdentity = new CellIdentityNr();
+ mCellSignalStrength = new CellSignalStrengthNr();
+ }
+
private CellInfoNr(Parcel in) {
super(in);
mCellIdentity = CellIdentityNr.CREATOR.createFromParcel(in);
@@ -71,6 +78,11 @@
return mCellIdentity;
}
+ /** @hide */
+ public void setCellIdentity(CellIdentityNr cid) {
+ mCellIdentity = cid;
+ }
+
/**
* @return a {@link CellSignalStrengthNr} instance.
*/
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index 21bef00..9bf2f44 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -203,10 +203,10 @@
for (String key : participantData.keySet()) {
sb.append(key);
sb.append("=");
- if (ENDPOINT.equals(key) || USER.equals(key)) {
- sb.append(Rlog.pii(TAG, participantData.get(key)));
- } else {
+ if (STATUS.equals(key)) {
sb.append(participantData.get(key));
+ } else {
+ sb.append(Rlog.pii(TAG, participantData.get(key)));
}
sb.append(", ");
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 7069e0a..2cdf70e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -29,6 +29,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.RemoteCallbackListExt;
+import com.android.internal.util.ArrayUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -105,6 +106,11 @@
// Locked on mLock, create unspecified disconnect cause.
private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo();
+ // We hold onto the uris each time they change so that we can send it to a callback when its
+ // first added.
+ private Uri[] mUris = new Uri[0];
+ private boolean mUrisSet = false;
+
/**
* @hide
*/
@@ -208,19 +214,27 @@
}
/**
- * The this device's subscriber associated {@link Uri}s have changed, which are used to filter
- * out this device's {@link Uri}s during conference calling.
- * @param uris
+ * Invoked when the {@link Uri}s associated to this device's subscriber have changed.
+ * These {@link Uri}s' are filtered out during conference calls.
+ *
+ * The {@link Uri}s are not guaranteed to be different between subsequent calls.
+ * @param uris changed uris
*/
public final void onSubscriberAssociatedUriChanged(Uri[] uris) {
- mCallbacks.broadcastAction((c) -> {
- try {
- c.onSubscriberAssociatedUriChanged(uris);
- } catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping " +
- "callback.");
- }
- });
+ synchronized (mLock) {
+ mUris = ArrayUtils.cloneOrNull(uris);
+ mUrisSet = true;
+ }
+ mCallbacks.broadcastAction((c) -> onSubscriberAssociatedUriChanged(c, uris));
+ }
+
+ private void onSubscriberAssociatedUriChanged(IImsRegistrationCallback callback, Uri[] uris) {
+ try {
+ callback.onSubscriberAssociatedUriChanged(uris);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping "
+ + "callback.");
+ }
}
private void updateToState(@ImsRegistrationTech int connType, int newState) {
@@ -233,6 +247,10 @@
private void updateToDisconnectedState(ImsReasonInfo info) {
synchronized (mLock) {
+ //We don't want to send this info over if we are disconnected
+ mUrisSet = false;
+ mUris = null;
+
updateToState(REGISTRATION_TECH_NONE,
RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
if (info != null) {
@@ -260,12 +278,17 @@
* @param c the newly registered callback that will be updated with the current registration
* state.
*/
- private void updateNewCallbackWithState(IImsRegistrationCallback c) throws RemoteException {
+ private void updateNewCallbackWithState(IImsRegistrationCallback c)
+ throws RemoteException {
int state;
ImsReasonInfo disconnectInfo;
+ boolean urisSet;
+ Uri[] uris;
synchronized (mLock) {
state = mRegistrationState;
disconnectInfo = mLastDisconnectCause;
+ urisSet = mUrisSet;
+ uris = mUris;
}
switch (state) {
case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: {
@@ -285,5 +308,8 @@
break;
}
}
+ if (urisSet) {
+ onSubscriberAssociatedUriChanged(c, uris);
+ }
}
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 4ccf79a..de1c5759 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -30,6 +30,7 @@
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -49,6 +50,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.NotificationManager;
@@ -65,6 +67,7 @@
import android.net.IpPrefix;
import android.net.IpSecManager;
import android.net.LinkProperties;
+import android.net.LocalSocket;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
@@ -74,6 +77,7 @@
import android.net.VpnService;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Process;
@@ -101,13 +105,20 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.net.Inet4Address;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
/**
@@ -133,7 +144,8 @@
managedProfileA.profileGroupId = primaryUser.id;
}
- static final String TEST_VPN_PKG = "com.dummy.vpn";
+ static final String EGRESS_IFACE = "wlan0";
+ static final String TEST_VPN_PKG = "com.testvpn.vpn";
private static final String TEST_VPN_SERVER = "1.2.3.4";
private static final String TEST_VPN_IDENTITY = "identity";
private static final byte[] TEST_VPN_PSK = "psk".getBytes();
@@ -1012,31 +1024,190 @@
// a subsequent CL.
}
- @Test
- public void testStartLegacyVpn() throws Exception {
+ public Vpn startLegacyVpn(final VpnProfile vpnProfile) throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
// Dummy egress interface
- final String egressIface = "DUMMY0";
final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(egressIface);
+ lp.setInterfaceName(EGRESS_IFACE);
final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
- InetAddresses.parseNumericAddress("192.0.2.0"), egressIface);
+ InetAddresses.parseNumericAddress("192.0.2.0"), EGRESS_IFACE);
lp.addRoute(defaultRoute);
- vpn.startLegacyVpn(mVpnProfile, mKeyStore, lp);
+ vpn.startLegacyVpn(vpnProfile, mKeyStore, lp);
+ return vpn;
+ }
+ @Test
+ public void testStartPlatformVpn() throws Exception {
+ startLegacyVpn(mVpnProfile);
// TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in
- // a subsequent CL.
+ // a subsequent patch.
+ }
+
+ @Test
+ public void testStartRacoonNumericAddress() throws Exception {
+ startRacoon("1.2.3.4", "1.2.3.4");
+ }
+
+ @Test
+ public void testStartRacoonHostname() throws Exception {
+ startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve
+ }
+
+ public void startRacoon(final String serverAddr, final String expectedAddr)
+ throws Exception {
+ final ConditionVariable legacyRunnerReady = new ConditionVariable();
+ final VpnProfile profile = new VpnProfile("testProfile" /* key */);
+ profile.type = VpnProfile.TYPE_L2TP_IPSEC_PSK;
+ profile.name = "testProfileName";
+ profile.username = "userName";
+ profile.password = "thePassword";
+ profile.server = serverAddr;
+ profile.ipsecIdentifier = "id";
+ profile.ipsecSecret = "secret";
+ profile.l2tpSecret = "l2tpsecret";
+ when(mConnectivityManager.getAllNetworks())
+ .thenReturn(new Network[] { new Network(101) });
+ when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(),
+ anyInt(), any(), anyInt())).thenAnswer(invocation -> {
+ // The runner has registered an agent and is now ready.
+ legacyRunnerReady.open();
+ return new Network(102);
+ });
+ final Vpn vpn = startLegacyVpn(profile);
+ final TestDeps deps = (TestDeps) vpn.mDeps;
+ try {
+ // udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK
+ assertArrayEquals(
+ new String[] { EGRESS_IFACE, expectedAddr, "udppsk",
+ profile.ipsecIdentifier, profile.ipsecSecret, "1701" },
+ deps.racoonArgs.get(10, TimeUnit.SECONDS));
+ // literal values are hardcoded in Vpn.java for mtpd args
+ assertArrayEquals(
+ new String[] { EGRESS_IFACE, "l2tp", expectedAddr, "1701", profile.l2tpSecret,
+ "name", profile.username, "password", profile.password,
+ "linkname", "vpn", "refuse-eap", "nodefaultroute", "usepeerdns",
+ "idle", "1800", "mtu", "1400", "mru", "1400" },
+ deps.mtpdArgs.get(10, TimeUnit.SECONDS));
+ // Now wait for the runner to be ready before testing for the route.
+ legacyRunnerReady.block(10_000);
+ // In this test the expected address is always v4 so /32
+ final RouteInfo expectedRoute = new RouteInfo(new IpPrefix(expectedAddr + "/32"),
+ RouteInfo.RTN_THROW);
+ assertTrue("Routes lack the expected throw route (" + expectedRoute + ") : "
+ + vpn.mConfig.routes,
+ vpn.mConfig.routes.contains(expectedRoute));
+ } finally {
+ // Now interrupt the thread, unblock the runner and clean up.
+ vpn.mVpnRunner.exitVpnRunner();
+ deps.getStateFile().delete(); // set to delete on exit, but this deletes it earlier
+ vpn.mVpnRunner.join(10_000); // wait for up to 10s for the runner to die and cleanup
+ }
+ }
+
+ private static final class TestDeps extends Vpn.Dependencies {
+ public final CompletableFuture<String[]> racoonArgs = new CompletableFuture();
+ public final CompletableFuture<String[]> mtpdArgs = new CompletableFuture();
+ public final File mStateFile;
+
+ private final HashMap<String, Boolean> mRunningServices = new HashMap<>();
+
+ TestDeps() {
+ try {
+ mStateFile = File.createTempFile("vpnTest", ".tmp");
+ mStateFile.deleteOnExit();
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void startService(final String serviceName) {
+ mRunningServices.put(serviceName, true);
+ }
+
+ @Override
+ public void stopService(final String serviceName) {
+ mRunningServices.put(serviceName, false);
+ }
+
+ @Override
+ public boolean isServiceRunning(final String serviceName) {
+ return mRunningServices.getOrDefault(serviceName, false);
+ }
+
+ @Override
+ public boolean isServiceStopped(final String serviceName) {
+ return !isServiceRunning(serviceName);
+ }
+
+ @Override
+ public File getStateFile() {
+ return mStateFile;
+ }
+
+ @Override
+ public void sendArgumentsToDaemon(
+ final String daemon, final LocalSocket socket, final String[] arguments,
+ final Vpn.RetryScheduler interruptChecker) throws IOException {
+ if ("racoon".equals(daemon)) {
+ racoonArgs.complete(arguments);
+ } else if ("mtpd".equals(daemon)) {
+ writeStateFile(arguments);
+ mtpdArgs.complete(arguments);
+ } else {
+ throw new UnsupportedOperationException("Unsupported daemon : " + daemon);
+ }
+ }
+
+ private void writeStateFile(final String[] arguments) throws IOException {
+ mStateFile.delete();
+ mStateFile.createNewFile();
+ mStateFile.deleteOnExit();
+ final BufferedWriter writer = new BufferedWriter(
+ new FileWriter(mStateFile, false /* append */));
+ writer.write(EGRESS_IFACE);
+ writer.write("\n");
+ // addresses
+ writer.write("10.0.0.1/24\n");
+ // routes
+ writer.write("192.168.6.0/24\n");
+ // dns servers
+ writer.write("192.168.6.1\n");
+ // search domains
+ writer.write("vpn.searchdomains.com\n");
+ // endpoint - intentionally empty
+ writer.write("\n");
+ writer.flush();
+ writer.close();
+ }
+
+ @Override
+ @NonNull
+ public InetAddress resolve(final String endpoint) {
+ try {
+ // If a numeric IP address, return it.
+ return InetAddress.parseNumericAddress(endpoint);
+ } catch (IllegalArgumentException e) {
+ // Otherwise, return some token IP to test for.
+ return InetAddress.parseNumericAddress("5.6.7.8");
+ }
+ }
+
+ @Override
+ public boolean checkInterfacePresent(final Vpn vpn, final String iface) {
+ return true;
+ }
}
/**
* Mock some methods of vpn object.
*/
private Vpn createVpn(@UserIdInt int userId) {
- return new Vpn(Looper.myLooper(), mContext, mNetService,
+ return new Vpn(Looper.myLooper(), mContext, new TestDeps(), mNetService,
userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
index c91dfec..7726c66 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
@@ -29,6 +29,7 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.net.NetworkTemplate;
import android.os.Looper;
@@ -135,6 +136,11 @@
mMonitor.onSubscriptionsChanged();
}
+ private void updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId) {
+ when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId);
+ mMonitor.onSubscriptionsChanged();
+ }
+
private void removeTestSub(int subId) {
// Remove subId from TestSubList.
mTestSubList.removeIf(it -> it == subId);
@@ -268,4 +274,54 @@
listener.onServiceStateChanged(serviceState);
assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
}
+
+ @Test
+ public void testSubscriberIdUnavailable() {
+ final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor =
+ ArgumentCaptor.forClass(RatTypeListener.class);
+
+ mMonitor.start();
+ // Insert sim1, set subscriberId to null which is normal in SIM PIN locked case.
+ // Verify RAT type is NETWORK_TYPE_UNKNOWN and service will not perform listener
+ // registration.
+ addTestSub(TEST_SUBID1, null);
+ verify(mTelephonyManager, never()).listen(any(), anyInt());
+ assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+
+ // Set IMSI for sim1, verify the listener will be registered.
+ updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1);
+ verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(),
+ eq(PhoneStateListener.LISTEN_SERVICE_STATE));
+ reset(mTelephonyManager);
+ when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+
+ // Set RAT type of sim1 to UMTS. Verify RAT type of sim1 is changed.
+ setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
+ TelephonyManager.NETWORK_TYPE_UMTS);
+ assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
+ reset(mDelegate);
+
+ // Set IMSI to null again to simulate somehow IMSI is not available, such as
+ // modem crash. Verify service should not unregister listener.
+ updateSubscriberIdForTestSub(TEST_SUBID1, null);
+ verify(mTelephonyManager, never()).listen(any(), anyInt());
+ assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
+ reset(mDelegate);
+
+ // Set RAT type of sim1 to LTE. Verify RAT type of sim1 is still changed even if the IMSI
+ // is not available. The monitor keeps the listener even if the IMSI disappears because
+ // the IMSI can never change for any given subId, therefore even if the IMSI is updated
+ // to null, the monitor should continue accepting updates of the RAT type. However,
+ // telephony is never actually supposed to do this, if the IMSI disappears there should
+ // not be updates, but it's still the right thing to do theoretically.
+ setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
+ TelephonyManager.NETWORK_TYPE_LTE);
+ assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE);
+ reset(mDelegate);
+
+ mMonitor.stop();
+ verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()),
+ eq(PhoneStateListener.LISTEN_NONE));
+ assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+ }
}
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index a5e76e6..d2ff658 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -533,6 +533,7 @@
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case SECURITY_TYPE_WPA2_PSK:
+ case SECURITY_TYPE_WPA3_SAE_TRANSITION:
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
break;
default:
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index fa806e7..282757a 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -448,6 +448,16 @@
return new UserCredential[size];
}
};
+
+ /**
+ * Get a unique identifier for UserCredential.
+ *
+ * @hide
+ * @return a Unique identifier for a UserCredential object
+ */
+ public int getUniqueId() {
+ return Objects.hash(mUsername);
+ }
}
private UserCredential mUserCredential = null;
/**
@@ -1037,7 +1047,8 @@
* @return a Unique identifier for a Credential object
*/
public int getUniqueId() {
- return Objects.hash(mUserCredential, mCertCredential, mSimCredential, mRealm);
+ return Objects.hash(mUserCredential != null ? mUserCredential.getUniqueId() : 0,
+ mCertCredential, mSimCredential, mRealm);
}
@Override
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 224c4be..8f34579 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -313,9 +313,7 @@
* @return a Unique identifier for a HomeSp object
*/
public int getUniqueId() {
- return Objects.hash(mFqdn, mFriendlyName, mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
- Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
- Arrays.hashCode(mRoamingConsortiumOis));
+ return Objects.hash(mFqdn);
}
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
index c0d60c3..641b891 100644
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ b/wifi/tests/src/android/net/wifi/FakeKeys.java
@@ -214,6 +214,35 @@
};
public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
+ private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n"
+ + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n"
+ + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n"
+ + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n"
+ + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n"
+ + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n"
+ + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n"
+ + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n"
+ + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n"
+ + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n"
+ + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n"
+ + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n"
+ + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n"
+ + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n"
+ + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n"
+ + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n"
+ + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n"
+ + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n"
+ + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n"
+ + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n"
+ + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n"
+ + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n"
+ + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n"
+ + "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT =
+ loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING);
+
private static X509Certificate loadCertificate(String blob) {
try {
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index 1a44270..d78c942 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -282,12 +282,6 @@
.build();
assertNull(band_6g_config.toWifiConfiguration());
- SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .build();
-
- assertNull(sae_transition_config.toWifiConfiguration());
}
@Test
@@ -330,5 +324,16 @@
assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY);
assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0);
assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true);
+
+ SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder()
+ .setPassphrase("secretsecret",
+ SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
+ .build();
+
+ WifiConfiguration wifiConfig_sae_transition =
+ softApConfig_sae_transition.toWifiConfiguration();
+ assertThat(wifiConfig_sae_transition.getAuthType())
+ .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret");
}
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 638efb9..8270d64 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -23,6 +23,8 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import android.net.wifi.EAPConstants;
+import android.net.wifi.FakeKeys;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Parcel;
@@ -32,6 +34,11 @@
import org.junit.Test;
import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -383,19 +390,39 @@
}
/**
- * Verify that the unique identifier generated is different for two instances with different
- * HomeSp node
+ * Verify that the unique identifier generated is the same for two instances with different
+ * HomeSp node but same FQDN
*
* @throws Exception
*/
@Test
- public void validateUniqueIdDifferentHomeSp() throws Exception {
+ public void validateUniqueIdDifferentHomeSpSameFqdn() throws Exception {
PasspointConfiguration config1 = PasspointTestUtils.createConfig();
- // Modify config2's RCOIs to a different set of values
+ // Modify config2's RCOIs and friendly name to a different set of values
PasspointConfiguration config2 = PasspointTestUtils.createConfig();
HomeSp homeSp = config2.getHomeSp();
homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb});
+ homeSp.setFriendlyName("Some other name");
+ config2.setHomeSp(homeSp);
+
+ assertEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with the same
+ * HomeSp node but different FQDN
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdSameHomeSpDifferentFqdn() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+
+ // Modify config2's FQDN to a different value
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ HomeSp homeSp = config2.getHomeSp();
+ homeSp.setFqdn("fqdn2.com");
config2.setHomeSp(homeSp);
assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
@@ -403,15 +430,15 @@
/**
* Verify that the unique identifier generated is different for two instances with different
- * Credential node
+ * SIM Credential node
*
* @throws Exception
*/
@Test
- public void validateUniqueIdDifferentCredential() throws Exception {
+ public void validateUniqueIdDifferentSimCredential() throws Exception {
PasspointConfiguration config1 = PasspointTestUtils.createConfig();
- // Modify config2's RCOIs to a different set of values
+ // Modify config2's realm and SIM credential to a different set of values
PasspointConfiguration config2 = PasspointTestUtils.createConfig();
Credential credential = config2.getCredential();
credential.setRealm("realm2.example.com");
@@ -422,6 +449,157 @@
}
/**
+ * Verify that the unique identifier generated is different for two instances with different
+ * Realm in the Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentRealm() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+
+ // Modify config2's realm to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ Credential credential = config2.getCredential();
+ credential.setRealm("realm2.example.com");
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is the same for two instances with different
+ * password and same username in the User Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdSameUserInUserCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithUserCredential("user", "passwd");
+ config1.setCredential(credential);
+
+ // Modify config2's Passpowrd to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithUserCredential("user", "newpasswd");
+ config2.setCredential(credential);
+
+ assertEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with different
+ * username in the User Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentUserCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithUserCredential("user", "passwd");
+ config1.setCredential(credential);
+
+ // Modify config2's username to a different value
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithUserCredential("user2", "passwd");
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with different
+ * Cert Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentCertCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithCertificateCredential(true, true);
+ config1.setCredential(credential);
+
+ // Modify config2's cert credential to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithCertificateCredential(false, false);
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Helper function for generating certificate credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private static Credential createCredentialWithCertificateCredential(Boolean useCaCert0,
+ Boolean useCert0)
+ throws NoSuchAlgorithmException, CertificateEncodingException {
+ Credential.CertificateCredential certCred = new Credential.CertificateCredential();
+ certCred.setCertType("x509v3");
+ if (useCert0) {
+ certCred.setCertSha256Fingerprint(
+ MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
+ } else {
+ certCred.setCertSha256Fingerprint(MessageDigest.getInstance("SHA-256")
+ .digest(FakeKeys.CLIENT_SUITE_B_RSA3072_CERT.getEncoded()));
+ }
+ return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
+ FakeKeys.RSA_KEY1, useCaCert0 ? FakeKeys.CA_CERT0 : FakeKeys.CA_CERT1);
+ }
+
+ /**
+ * Helper function for generating user credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private static Credential createCredentialWithUserCredential(String username, String password) {
+ Credential.UserCredential userCred = new Credential.UserCredential();
+ userCred.setUsername(username);
+ userCred.setPassword(password);
+ userCred.setMachineManaged(true);
+ userCred.setAbleToShare(true);
+ userCred.setSoftTokenApp("TestApp");
+ userCred.setEapType(EAPConstants.EAP_TTLS);
+ userCred.setNonEapInnerMethod("MS-CHAP");
+ return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
+ }
+
+ /**
+ * Helper function for generating Credential for testing.
+ *
+ * @param userCred Instance of UserCredential
+ * @param certCred Instance of CertificateCredential
+ * @param simCred Instance of SimCredential
+ * @param clientCertificateChain Chain of client certificates
+ * @param clientPrivateKey Client private key
+ * @param caCerts CA certificates
+ * @return {@link Credential}
+ */
+ private static Credential createCredential(Credential.UserCredential userCred,
+ Credential.CertificateCredential certCred,
+ Credential.SimCredential simCred,
+ X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
+ X509Certificate... caCerts) {
+ Credential cred = new Credential();
+ cred.setCreationTimeInMillis(123455L);
+ cred.setExpirationTimeInMillis(2310093L);
+ cred.setRealm("realm");
+ cred.setCheckAaaServerCertStatus(true);
+ cred.setUserCredential(userCred);
+ cred.setCertCredential(certCred);
+ cred.setSimCredential(simCred);
+ if (caCerts != null && caCerts.length == 1) {
+ cred.setCaCertificate(caCerts[0]);
+ } else {
+ cred.setCaCertificates(caCerts);
+ }
+ cred.setClientCertificateChain(clientCertificateChain);
+ cred.setClientPrivateKey(clientPrivateKey);
+ return cred;
+ }
+
+ /**
* Verify that the unique identifier API generates an exception if HomeSP is not initialized.
*
* @throws Exception
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index 829d8f0..a44df40 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -593,10 +593,10 @@
}
/**
- * Verify that unique identifiers are different for a credential with different values
+ * Verify that unique identifiers are different for a credential with different username
*/
@Test
- public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception {
+ public void testUniqueIdDifferentForUserCredentialsWithDifferentUsername() throws Exception {
Credential userCred1 = createCredentialWithUserCredential();
Credential userCred2 = createCredentialWithUserCredential();
userCred2.getUserCredential().setUsername("anotheruser");
@@ -605,7 +605,24 @@
}
/**
- * Verify that unique identifiers are different for a credential with different values
+ * Verify that unique identifiers are different for a credential with different password and
+ * other values other than username
+ */
+ @Test
+ public void testUniqueIdSameForUserCredentialsWithDifferentPassword() throws Exception {
+ Credential userCred1 = createCredentialWithUserCredential();
+ Credential userCred2 = createCredentialWithUserCredential();
+ userCred2.getUserCredential().setPassword("someotherpassword!");
+ userCred2.getUserCredential().setMachineManaged(false);
+ userCred2.getUserCredential().setAbleToShare(false);
+ userCred2.getUserCredential().setSoftTokenApp("TestApp2");
+ userCred2.getUserCredential().setNonEapInnerMethod("PAP");
+
+ assertEquals(userCred1.getUniqueId(), userCred2.getUniqueId());
+ }
+
+ /**
+ * Verify that unique identifiers are different for a cert credential with different values
*/
@Test
public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception {