Merge "Hide IME adjust dims when divider is hidden" into rvc-dev
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index 68c27a8..c43fabd 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -21,12 +21,18 @@
path: "java",
}
-java_library {
+java_sdk_library {
name: "framework-permission",
+ defaults: ["framework-module-defaults"],
srcs: [
":framework-permission-sources",
],
- sdk_version: "module_current",
+
+ // TODO(b/155480189) - Remove naming_scheme once references have been resolved.
+ // Temporary java_sdk_library component naming scheme to use to ease the transition from separate
+ // modules to java_sdk_library.
+ naming_scheme: "framework-modules",
+
apex_available: [
"com.android.permission",
"test_com.android.permission",
@@ -40,91 +46,5 @@
visibility: [
"//frameworks/base/apex/permission:__subpackages__",
],
-}
-
-stubs_defaults {
- name: "framework-permission-stubs-defaults",
- srcs: [ ":framework-permission-sources" ],
- libs: [ "framework-annotations-lib" ],
- dist: { dest: "framework-permission.txt" },
-}
-
-droidstubs {
- name: "framework-permission-stubs-srcs-publicapi",
- defaults: [
- "framework-module-stubs-defaults-publicapi",
- "framework-permission-stubs-defaults",
- ],
- check_api: {
- last_released: {
- api_file: ":framework-permission.api.public.latest",
- removed_api_file: ":framework-permission-removed.api.public.latest",
- },
- api_lint: {
- new_since: ":framework-permission.api.public.latest",
- },
- },
-}
-
-droidstubs {
- name: "framework-permission-stubs-srcs-systemapi",
- defaults: [
- "framework-module-stubs-defaults-systemapi",
- "framework-permission-stubs-defaults",
- ],
- check_api: {
- last_released: {
- api_file: ":framework-permission.api.system.latest",
- removed_api_file: ":framework-permission-removed.api.system.latest",
- },
- api_lint: {
- new_since: ":framework-permission.api.system.latest",
- },
- },
-}
-
-droidstubs {
- name: "framework-permission-api-module_libs_api",
- defaults: [
- "framework-module-api-defaults-module_libs_api",
- "framework-permission-stubs-defaults",
- ],
- check_api: {
- last_released: {
- api_file: ":framework-permission.api.module-lib.latest",
- removed_api_file: ":framework-permission-removed.api.module-lib.latest",
- },
- api_lint: {
- new_since: ":framework-permission.api.module-lib.latest",
- },
- },
-}
-
-droidstubs {
- name: "framework-permission-stubs-srcs-module_libs_api",
- defaults: [
- "framework-module-stubs-defaults-module_libs_api",
- "framework-permission-stubs-defaults",
- ],
-}
-
-java_library {
- name: "framework-permission-stubs-publicapi",
- srcs: [ ":framework-permission-stubs-srcs-publicapi" ],
- defaults: ["framework-module-stubs-lib-defaults-publicapi"],
- dist: { dest: "framework-permission.jar" },
-}
-
-java_library {
- name: "framework-permission-stubs-systemapi",
- srcs: [ ":framework-permission-stubs-srcs-systemapi" ],
- defaults: ["framework-module-stubs-lib-defaults-systemapi"],
- dist: { dest: "framework-permission.jar" },
-}
-
-java_library {
- name: "framework-permission-stubs-module_libs_api",
- srcs: [ ":framework-permission-stubs-srcs-module_libs_api" ],
- defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
- dist: { dest: "framework-permission.jar" },
+ stubs_library_visibility: ["//visibility:public"],
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 8ba52ef..573a84f 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -4945,9 +4945,12 @@
/**
* Used for pull network statistics via mobile|wifi networks, and sliced by interesting dimensions.
- * Note that data is expected to be sliced into more dimensions in future. In other words,
- * the caller must not assume the data is unique when filtering with a set of matching conditions.
- * Thus, as the dimension grows, the caller will not be affected.
+ * Note that the data is expected to be sliced into more dimensions in future. In other words,
+ * the caller must not assume any row of data is one full report when filtering with a set of
+ * matching conditions, because future data may represent with multiple rows what is currently
+ * represented by one.
+ * To avoid being broken by future slicing, callers must take care to aggregate rows even if they
+ * query all the existing columns.
*
* Pulled from:
* StatsPullAtomService (using NetworkStatsService to get NetworkStats)
@@ -4972,21 +4975,26 @@
optional int32 rat_type = 6;
// Mcc/Mnc read from sim if the record is for a specific subscription, null indicates the
- // record is combined regardless of subscription.
+ // record is combined across subscriptions.
optional string sim_mcc = 7;
optional string sim_mnc = 8;
+ // Allows mobile virtual network operators (MVNOs) to be identified with individual IDs.
+ // See TelephonyManager#getSimCarrierId.
+ optional int32 carrier_id = 9;
+
// Enumeration of opportunistic states with an additional ALL state indicates the record is
// combined regardless of the boolean value in its field.
enum DataSubscriptionState {
+ UNKNOWN = 0; // For server side backward compatibility.
ALL = 1;
OPPORTUNISTIC = 2;
NOT_OPPORTUNISTIC = 3;
}
// Mark whether the subscription is an opportunistic data subscription, and ALL indicates the
- // record is combined regardless of opportunistic data subscription.
+ // record is combined across opportunistic data subscriptions.
// See {@link SubscriptionManager#setOpportunistic}.
- optional DataSubscriptionState opportunistic_data_sub = 9;
+ optional DataSubscriptionState opportunistic_data_sub = 10;
}
/**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 16e5156..66b8cab 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -162,12 +162,9 @@
/** {@hide} */
public static final String PROP_SETTINGS_FUSE = FeatureFlagUtils.PERSIST_PREFIX
+ FeatureFlagUtils.SETTINGS_FUSE_FLAG;
- /**
- * Property that determines whether {@link OP_LEGACY_STORAGE} is sticky for
- * legacy apps.
- * @hide
- */
- public static final String PROP_LEGACY_OP_STICKY = "persist.sys.legacy_storage_sticky";
+ /** {@hide} */
+ public static final String PROP_FORCED_SCOPED_STORAGE_WHITELIST =
+ "forced_scoped_storage_whitelist";
/** {@hide} */
public static final String UUID_PRIVATE_INTERNAL = null;
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index da7503d..1dd4cbb 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -227,11 +227,8 @@
}
}
- if (mNewName.exists()) {
- if (!mNewName.delete()) {
- Log.e(LOG_TAG, "Failed to delete outdated new file " + mNewName);
- }
- }
+ // Don't delete mNewName here - it was okay to call openRead() between startWrite() and
+ // finishWrite(), and we have to keep supporting it.
return new FileInputStream(mBaseName);
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index d12a122..758062f 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -568,15 +568,11 @@
private void updateState(InsetsState newState) {
mState.setDisplayFrame(newState.getDisplayFrame());
for (int i = newState.getSourcesCount() - 1; i >= 0; i--) {
- final InsetsSource source = newState.sourceAt(i);
- final int type = source.getType();
- final InsetsSourceConsumer consumer = getSourceConsumer(type);
- consumer.updateSource(source);
- mHost.updateCompatSysUiVisibility(type, source.isVisible(),
- consumer.getControl() != null);
+ InsetsSource source = newState.sourceAt(i);
+ getSourceConsumer(source.getType()).updateSource(source);
}
for (int i = mState.getSourcesCount() - 1; i >= 0; i--) {
- final InsetsSource source = mState.sourceAt(i);
+ InsetsSource source = mState.sourceAt(i);
if (newState.peekSource(source.getType()) == null) {
mState.removeSource(source.getType());
}
@@ -1011,6 +1007,14 @@
}
/**
+ * @see ViewRootImpl#updateCompatSysUiVisibility(int, boolean, boolean)
+ */
+ public void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible,
+ boolean hasControl) {
+ mHost.updateCompatSysUiVisibility(type, visible, hasControl);
+ }
+
+ /**
* Called when current window gains focus.
*/
public void onWindowFocusGained() {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index a0cdcfe..df3ac87 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -18,6 +18,7 @@
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
import static android.view.InsetsController.AnimationType;
+import static android.view.InsetsState.getDefaultVisibility;
import static android.view.InsetsState.toPublicType;
import android.annotation.IntDef;
@@ -82,7 +83,7 @@
mState = state;
mTransactionSupplier = transactionSupplier;
mController = controller;
- mRequestedVisible = InsetsState.getDefaultVisibility(type);
+ mRequestedVisible = getDefaultVisibility(type);
}
/**
@@ -200,12 +201,20 @@
}
boolean applyLocalVisibilityOverride() {
+ final InsetsSource source = mState.peekSource(mType);
+ final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility(mType);
+ final boolean hasControl = mSourceControl != null;
+
+ // We still need to let the legacy app know the visibility change even if we don't have the
+ // control.
+ mController.updateCompatSysUiVisibility(
+ mType, hasControl ? mRequestedVisible : isVisible, hasControl);
// If we don't have control, we are not able to change the visibility.
- if (mSourceControl == null) {
+ if (!hasControl) {
return false;
}
- if (mState.getSource(mType).isVisible() == mRequestedVisible) {
+ if (isVisible == mRequestedVisible) {
return false;
}
mState.getSource(mType).setVisible(mRequestedVisible);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d928356..511e755 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1977,6 +1977,7 @@
(mCompatibleVisibilityInfo.globalVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE)
| (mAttachInfo.mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
if (mDispatchedSystemUiVisibility != mCompatibleVisibilityInfo.globalVisibility) {
+ mHandler.removeMessages(MSG_DISPATCH_SYSTEM_UI_VISIBILITY);
mHandler.sendMessage(mHandler.obtainMessage(
MSG_DISPATCH_SYSTEM_UI_VISIBILITY, mCompatibleVisibilityInfo));
}
@@ -2031,8 +2032,10 @@
}
} else {
info.globalVisibility |= systemUiFlag;
+ info.localChanges &= ~systemUiFlag;
}
if (mDispatchedSystemUiVisibility != info.globalVisibility) {
+ mHandler.removeMessages(MSG_DISPATCH_SYSTEM_UI_VISIBILITY);
mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, info));
}
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 39c7210..301ce9f 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -166,6 +166,8 @@
public static final int FLUSH_REASON_IDLE_TIMEOUT = 5;
/** @hide */
public static final int FLUSH_REASON_TEXT_CHANGE_TIMEOUT = 6;
+ /** @hide */
+ public static final int FLUSH_REASON_SESSION_CONNECTED = 7;
/** @hide */
@IntDef(prefix = { "FLUSH_REASON_" }, value = {
@@ -174,7 +176,8 @@
FLUSH_REASON_SESSION_STARTED,
FLUSH_REASON_SESSION_FINISHED,
FLUSH_REASON_IDLE_TIMEOUT,
- FLUSH_REASON_TEXT_CHANGE_TIMEOUT
+ FLUSH_REASON_TEXT_CHANGE_TIMEOUT,
+ FLUSH_REASON_SESSION_CONNECTED
})
@Retention(RetentionPolicy.SOURCE)
public @interface FlushReason{}
@@ -609,6 +612,8 @@
return "IDLE";
case FLUSH_REASON_TEXT_CHANGE_TIMEOUT:
return "TEXT_CHANGE";
+ case FLUSH_REASON_SESSION_CONNECTED:
+ return "CONNECTED";
default:
return "UNKOWN-" + reason;
}
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 893d38d..6eb71f7 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -273,6 +273,8 @@
} else {
mState = resultCode;
mDisabled.set(false);
+ // Flush any pending data immediately as buffering forced until now.
+ flushIfNeeded(FLUSH_REASON_SESSION_CONNECTED);
}
if (sVerbose) {
Log.v(TAG, "handleSessionStarted() result: id=" + mId + " resultCode=" + resultCode
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index f78ec7c..0807f41 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -219,17 +219,34 @@
}
/**
- * Tell the client to display a confirm dialog to the user. If the client
- * returns {@code true}, WebView will assume that the client will handle the
- * confirm dialog and call the appropriate JsResult method. If the
- * client returns false, a default value of {@code false} will be returned to
- * javascript. The default behavior is to return {@code false}.
+ * Notify the host application that the web page wants to display a
+ * JavaScript {@code confirm()} dialog.
+ * <p>The default behavior if this method returns {@code false} or is not
+ * overridden is to show a dialog containing the message and suspend
+ * JavaScript execution until the dialog is dismissed. The default dialog
+ * will return {@code true} to the JavaScript {@code confirm()} code when
+ * the user presses the 'confirm' button, and will return {@code false} to
+ * the JavaScript code when the user presses the 'cancel' button or
+ * dismisses the dialog.
+ * <p>To show a custom dialog, the app should return {@code true} from this
+ * method, in which case the default dialog will not be shown and JavaScript
+ * execution will be suspended. The app should call
+ * {@code JsResult.confirm()} or {@code JsResult.cancel()} when the custom
+ * dialog is dismissed.
+ * <p>To suppress the dialog and allow JavaScript execution to continue,
+ * call {@code JsResult.confirm()} or {@code JsResult.cancel()} immediately
+ * and then return {@code true}.
+ * <p>Note that if the {@link WebChromeClient} is {@code null}, the default
+ * dialog will be suppressed and the default value of {@code false} will be
+ * returned to the JavaScript code immediately.
+ *
* @param view The WebView that initiated the callback.
* @param url The url of the page requesting the dialog.
* @param message Message to be displayed in the window.
* @param result A JsResult used to send the user's response to
* javascript.
- * @return boolean Whether the client will handle the confirm dialog.
+ * @return boolean {@code true} if the request is handled or ignored.
+ * {@code false} if WebView needs to show the default dialog.
*/
public boolean onJsConfirm(WebView view, String url, String message,
JsResult result) {
@@ -237,18 +254,33 @@
}
/**
- * Tell the client to display a prompt dialog to the user. If the client
- * returns {@code true}, WebView will assume that the client will handle the
- * prompt dialog and call the appropriate JsPromptResult method. If the
- * client returns false, a default value of {@code false} will be returned to to
- * javascript. The default behavior is to return {@code false}.
+ * Notify the host application that the web page wants to display a
+ * JavaScript {@code prompt()} dialog.
+ * <p>The default behavior if this method returns {@code false} or is not
+ * overridden is to show a dialog containing the message and suspend
+ * JavaScript execution until the dialog is dismissed. Once the dialog is
+ * dismissed, JavaScript {@code prompt()} will return the string that the
+ * user typed in, or null if the user presses the 'cancel' button.
+ * <p>To show a custom dialog, the app should return {@code true} from this
+ * method, in which case the default dialog will not be shown and JavaScript
+ * execution will be suspended. The app should call
+ * {@code JsPromptResult.confirm(result)} when the custom dialog is
+ * dismissed.
+ * <p>To suppress the dialog and allow JavaScript execution to continue,
+ * call {@code JsPromptResult.confirm(result)} immediately and then
+ * return {@code true}.
+ * <p>Note that if the {@link WebChromeClient} is {@code null}, the default
+ * dialog will be suppressed and {@code null} will be returned to the
+ * JavaScript code immediately.
+ *
* @param view The WebView that initiated the callback.
* @param url The url of the page requesting the dialog.
* @param message Message to be displayed in the window.
* @param defaultValue The default value displayed in the prompt dialog.
* @param result A JsPromptResult used to send the user's reponse to
* javascript.
- * @return boolean Whether the client will handle the prompt dialog.
+ * @return boolean {@code true} if the request is handled or ignored.
+ * {@code false} if WebView needs to show the default dialog.
*/
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, JsPromptResult result) {
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index a47ad73..c8f5be4 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -62,6 +62,7 @@
private final Context mContext;
private int mCurrentPage;
private OnProfileSelectedListener mOnProfileSelectedListener;
+ private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener;
private Set<Integer> mLoadedPages;
private final UserHandle mPersonalProfileUserHandle;
private final UserHandle mWorkProfileUserHandle;
@@ -124,6 +125,10 @@
mOnProfileSelectedListener = listener;
}
+ void setOnSwitchOnWorkSelectedListener(OnSwitchOnWorkSelectedListener listener) {
+ mOnSwitchOnWorkSelectedListener = listener;
+ }
+
Context getContext() {
return mContext;
}
@@ -397,6 +402,9 @@
ProfileDescriptor descriptor = getItem(
userHandleToPageIndex(listAdapter.getUserHandle()));
showSpinner(descriptor.getEmptyStateView());
+ if (mOnSwitchOnWorkSelectedListener != null) {
+ mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected();
+ }
mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle);
});
return true;
@@ -576,6 +584,16 @@
}
/**
+ * Listener for when the user switches on the work profile from the work tab.
+ */
+ interface OnSwitchOnWorkSelectedListener {
+ /**
+ * Callback for when the user switches on the work profile from the work tab.
+ */
+ void onSwitchOnWorkSelected();
+ }
+
+ /**
* Describes an injector to be used for cross profile functionality. Overridable for testing.
*/
@VisibleForTesting
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 4b5735c..182c7f2 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1662,6 +1662,13 @@
resetButtonBar();
resetCheckedItem();
});
+ mMultiProfilePagerAdapter.setOnSwitchOnWorkSelectedListener(
+ () -> {
+ final View workTab = tabHost.getTabWidget().getChildAt(1);
+ workTab.setFocusable(true);
+ workTab.setFocusableInTouchMode(true);
+ workTab.requestFocus();
+ });
findViewById(R.id.resolver_tab_divider).setVisibility(View.VISIBLE);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4bc570a..d4cc636 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5477,13 +5477,14 @@
<service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
android:exported="false">
<intent-filter>
- <action android:name="android.intent.action.LOAD_DATA" />
+ <action android:name="android.intent.action.LOAD_DATA"/>
</intent-filter>
</service>
<provider
android:name="com.android.server.textclassifier.IconsContentProvider"
android:authorities="com.android.textclassifier.icons"
+ android:singleUser="true"
android:enabled="true"
android:exported="true">
</provider>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fe7b0ae..ac808df 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -42,6 +42,7 @@
<item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_secure</xliff:g></item>
+ <item><xliff:g id="id">@string/status_bar_media</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_cast</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_screen_record</xliff:g></item>
@@ -96,6 +97,7 @@
<string translatable="false" name="status_bar_airplane">airplane</string>
<string translatable="false" name="status_bar_sensors_off">sensors_off</string>
<string translatable="false" name="status_bar_screen_record">screen_record</string>
+ <string translatable="false" name="status_bar_media">media</string>
<!-- Flag indicating whether the surface flinger has limited
alpha compositing functionality in hardware. If set, the window
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7744e9e..758a4f7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2916,6 +2916,7 @@
<java-symbol type="string" name="status_bar_camera" />
<java-symbol type="string" name="status_bar_sensors_off" />
<java-symbol type="string" name="status_bar_screen_record" />
+ <java-symbol type="string" name="status_bar_media" />
<!-- Locale picker -->
<java-symbol type="id" name="locale_search_menu" />
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index 1275cb9..eb940e2 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -30,8 +30,6 @@
/**
* {@usesMathJax}
*
- * <h3>Porter-Duff</h3>
- *
* <p>The name of the parent class is an homage to the work of Thomas Porter and
* Tom Duff, presented in their seminal 1984 paper titled "Compositing Digital Images".
* In this paper, the authors describe 12 compositing operators that govern how to
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index acd90a7..6df62c0 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -369,6 +369,13 @@
* {@link Activity#RESULT_OK} will be returned if a credential was
* successfully installed, otherwise {@link
* Activity#RESULT_CANCELED} will be returned.
+ *
+ * <p>Starting from {@link android.os.Build.VERSION_CODES#R}, the intent returned by this
+ * method cannot be used for installing CA certificates. Since CA certificates can only be
+ * installed via Settings, the app should provide the user with a file containing the
+ * CA certificate. One way to do this would be to use the {@link android.provider.MediaStore}
+ * API to write the certificate to the {@link android.provider.MediaStore.Downloads}
+ * collection.
*/
@NonNull
public static Intent createInstallIntent() {
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 357c333..b44d7bb 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -29,13 +29,13 @@
public abstract class AudioManagerInternal {
public abstract void adjustSuggestedStreamVolumeForUid(int streamType, int direction,
- int flags, String callingPackage, int uid);
+ int flags, String callingPackage, int uid, int pid);
public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid);
+ String callingPackage, int uid, int pid);
public abstract void setStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid);
+ String callingPackage, int uid, int pid);
public abstract void setRingerModeDelegate(RingerModeDelegate delegate);
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 1729027..66787c2 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Gedeaktiveer"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Werk-<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index fad7a82..ead0ebf 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ተሰናክሏል"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ነቅቷል"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"የእርስዎን መሣሪያ ይህ ለው ለማመልከት እንደገና መነሣት አለበት። አሁን እንደገና ያስነሡ ወይም ይተዉት።"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"የስራ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index b3cc832..c1f4fd9 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"اختيار ملف شخصي"</string>
<string name="category_personal" msgid="6236798763159385225">"شخصي"</string>
- <string name="category_work" msgid="4014193632325996115">"العمل"</string>
+ <string name="category_work" msgid="4014193632325996115">"للعمل"</string>
<string name="development_settings_title" msgid="140296922921597393">"خيارات مطور البرامج"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"تفعيل خيارات المطورين"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"تعيين خيارات تطوير التطبيق"</string>
@@ -279,7 +279,7 @@
<string name="private_dns_mode_off" msgid="7065962499349997041">"غير مفعّل"</string>
<string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"تلقائي"</string>
<string name="private_dns_mode_provider" msgid="3619040641762557028">"اسم مضيف مزوّد \"نظام أسماء النطاقات الخاص\""</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"يُرجى إدخال اسم مضيف \"مزوّد نظام أسماء النطاقات\""</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"يُرجى إدخال اسم مضيف DNS"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"تعذّر الاتصال"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
@@ -318,10 +318,10 @@
<string name="hdcp_checking_title" msgid="3155692785074095986">"التحقق من HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"تعيين سلوك التحقق من HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string>
- <string name="debug_app" msgid="8903350241392391766">"تحديد التطبيق لتصحيحه"</string>
+ <string name="debug_app" msgid="8903350241392391766">"اختيار التطبيق لتصحيحه"</string>
<string name="debug_app_not_set" msgid="1934083001283807188">"لم يتم تعيين تطبيق لتصحيحه"</string>
<string name="debug_app_set" msgid="6599535090477753651">"تطبيق التصحيح: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="select_application" msgid="2543228890535466325">"تحديد تطبيق"</string>
+ <string name="select_application" msgid="2543228890535466325">"اختيار تطبيق"</string>
<string name="no_application" msgid="9038334538870247690">"لا شيء"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"انتظار برنامج التصحيح"</string>
<string name="wait_for_debugger_summary" msgid="6846330006113363286">"ينتظر التطبيق قيد التصحيح انضمام برنامج التصحيح قبل التنفيذ"</string>
@@ -557,6 +557,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غير مفعّل"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"مفعّل"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"يجب إعادة تشغيل جهازك ليتم تطبيق هذا التغيير. يمكنك إعادة التشغيل الآن أو إلغاء التغيير."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> المخصّص للعمل"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index ad344c3..b5d642a 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
<string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ডিভাইচ ডিফ’ল্ট"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"অক্ষম কৰা আছে"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"সক্ষম কৰা আছে"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই সলনিটো কার্যকৰী হ’বলৈ আপোনাৰ ডিভাইচটো ৰিবুট কৰিবই লাগিব। এতিয়াই ৰিবুট কৰক অথবা বাতিল কৰক।"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"কৰ্মস্থান <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index ab7ea8c..aecaf70 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -155,7 +155,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"Bəzi susmaya görələr təyin edilib"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"Susmaya görələr təyin edilməyib."</string>
<string name="tts_settings" msgid="8130616705989351312">"Mətndən-danışığa parametrləri"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"Mətndən-nitqə çıxışı"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"Mətndən-nitqə daxiletmə"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Nitq diapazonu"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Mətnin səsləndirilmə sürəti"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"Pitç"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiv"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"İş <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index da47bf2..092bd42 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -554,6 +554,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 2761d47..d610973 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Выбраць профіль"</string>
<string name="category_personal" msgid="6236798763159385225">"Асабісты"</string>
- <string name="category_work" msgid="4014193632325996115">"Рабочы"</string>
+ <string name="category_work" msgid="4014193632325996115">"Працоўны"</string>
<string name="development_settings_title" msgid="140296922921597393">"Параметры распрацоўшчыка"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Уключыць параметры распрацоўшчыка"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Налада параметраў для распрацоўкі прыкладанняў"</string>
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Выключана"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Уключана"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Перазагрузіце прыладу, каб прымяніць гэта змяненне. Перазагрузіце ці скасуйце."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (праца)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8150710..5c3fe75 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -419,7 +419,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (червено – зелено)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (синьо – жълто)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекция на цветове"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Корекцията на цветове ви позволява да коригирате това, как цветовете се показват на устройството ви"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Функцията „Корекция на цветове“ ви позволява да коригирате това, как цветовете се показват на устройството ви"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Активирано"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да бъде приложена тази промяна, устройството ви трябва да бъде рестартирано. Рестартирайте сега или анулирайте."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> за работа"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 7bae6ee..27d3707 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"প্রোফাইল বেছে নিন"</string>
<string name="category_personal" msgid="6236798763159385225">"ব্যক্তিগত"</string>
- <string name="category_work" msgid="4014193632325996115">"কর্মক্ষেত্র"</string>
+ <string name="category_work" msgid="4014193632325996115">"অফিস"</string>
<string name="development_settings_title" msgid="140296922921597393">"ডেভেলপার বিকল্প"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ডেভেলপার বিকল্প সক্ষম করুন"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"অ্যাপ্লিকেশান উন্নয়নের জন্য বিকল্পগুলি সেট করুন"</string>
@@ -485,7 +485,7 @@
<string name="ims_reg_title" msgid="8197592958123671062">"IMS রেজিস্ট্রেশনের স্থিতি"</string>
<string name="ims_reg_status_registered" msgid="884916398194885457">"রেজিস্টার করা"</string>
<string name="ims_reg_status_not_registered" msgid="2989287366045704694">"রেজিস্টার করা নয়"</string>
- <string name="status_unavailable" msgid="5279036186589861608">"অনুপলব্ধ"</string>
+ <string name="status_unavailable" msgid="5279036186589861608">"অনুপলভ্য"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC র্যান্ডমাইজ করা হয়েছে"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="one">%1$dটি ডিভাইস কানেক্ট</item>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string>
<string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ডিভাইসের ডিফল্ট"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"বন্ধ করা আছে"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"চালু করা আছে"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই পরিবর্তনটি প্রয়োগ করার জন্য আপনার ডিভাইসটি অবশ্যই রিবুট করতে হবে। এখন রিবুট করুন বা বাতিল করুন।"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"অফিস <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 6489cef..6595c22 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -40,7 +40,7 @@
<item msgid="8339720953594087771">"Povezivanje na mrežu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="3028983857109369308">"Autentifikacija s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="4287401332778341890">"Dobivanje IP adrese iz mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="1043944043827424501">"Povezano na mrežu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1043944043827424501">"Povezano s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
<item msgid="7445993821842009653">"Suspendirano"</item>
<item msgid="1175040558087735707">"Prekidanje veze s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="699832486578171722">"Isključen"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index fe7f8c1..a9d9e70 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -452,7 +452,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo punjenje"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Priključen, trenutno se ne može puniti"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Priključeno, trenutno se ne može puniti"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"Puna"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pod kontrolom administratora"</string>
<string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
@@ -554,5 +554,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate ponovo pokrenuti uređaj da se ova promjena primijeni. Ponovo pokrenite odmah ili otkažite."</string>
- <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Poslovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 7dad950..5ed0f1b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -222,7 +222,7 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Empremta digital del dispositiu: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"No s\'ha pogut connectar"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Assegura\'t que <xliff:g id="DEVICE_NAME">%1$s</xliff:g> estigui connectat a la xarxa correcta"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Vincular amb el dispositiu"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Vincula amb el dispositiu"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Codi de vinculació Wi‑Fi"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"No s\'ha pogut vincular"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Assegura\'t que el dispositiu estigui connectat a la mateixa xarxa."</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivat"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Has de reiniciar el teu dispositiu perquè s\'apliquin els canvis. Reinicia\'l ara o cancel·la."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de la feina"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 51548f5..d4d3735 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuto"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuto"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aby se tato změna projevila, je třeba zařízení restartovat. Restartujte zařízení nebo zrušte akci."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Pracovní <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 88f8e92..89dbf25 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Enheden løber muligvis tør for batteri inden <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet aflades muligvis inden <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiveret"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiveret"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Din enhed skal genstartes for at denne enhed bliver anvendt. Genstart nu, eller annuller."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> – arbejde"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index edd1580..c2030b1 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -231,7 +231,7 @@
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Das Gerät konnte nicht gekoppelt werden. Der QR-Code war nicht korrekt oder das Gerät ist nicht mit demselben Netzwerk verbunden."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-Adresse & Port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR-Code scannen"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Scanne einen QR-Code, um ein Gerät über WLAN zu koppeln"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Scanne einen QR-Code, um das Gerät über WLAN zu koppeln"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Bitte stell eine WLAN-Verbindung her"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, Debug, Dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Verknüpfung zu Fehlerbericht"</string>
@@ -507,7 +507,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Dauer"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Jedes Mal fragen"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Bis zur Deaktivierung"</string>
- <string name="time_unit_just_now" msgid="3006134267292728099">"gerade eben"</string>
+ <string name="time_unit_just_now" msgid="3006134267292728099">"Gerade eben"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Smartphone-Lautsprecher"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus & und wieder ein."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiviert"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiviert"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Damit diese Änderung übernommen wird, musst du dein Gerät neu starten. Du kannst es jetzt neu starten oder den Vorgang abbrechen."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (geschäftlich)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c5c0e07..bfc183e 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -194,8 +194,8 @@
<item msgid="581904787661470707">"Ταχύτατη"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Επιλογή προφίλ"</string>
- <string name="category_personal" msgid="6236798763159385225">"Προσωπικό"</string>
- <string name="category_work" msgid="4014193632325996115">"Εργασία"</string>
+ <string name="category_personal" msgid="6236798763159385225">"Προσωπικός"</string>
+ <string name="category_work" msgid="4014193632325996115">"Εργασίας"</string>
<string name="development_settings_title" msgid="140296922921597393">"Επιλογές για προγραμματιστές"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Ενεργοποίηση επιλογών για προγραμματιστές"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ορισμός επιλογών για ανάπτυξη εφαρμογής"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ενεργή"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Για να εφαρμοστεί αυτή η αλλαγή, θα πρέπει να επανεκκινήσετε τη συσκευή σας. Επανεκκίνηση τώρα ή ακύρωση."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Εργασία <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index a1c8b04..9d869ba 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -229,7 +229,7 @@
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index a1c8b04..9d869ba 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -229,7 +229,7 @@
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index a1c8b04..9d869ba 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -229,7 +229,7 @@
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index a1c8b04..9d869ba 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -229,7 +229,7 @@
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 38ac8f1..7765824 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index c6d0d56..6a76beb 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencido"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencida"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
@@ -153,7 +153,7 @@
<string name="unknown" msgid="3544487229740637809">"Desconocido"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"Usuario: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"Configuraciones predeterminadas establecidas"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"No hay configuraciones predeterminadas establecidas."</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"No se establecieron configuraciones predeterminadas"</string>
<string name="tts_settings" msgid="8130616705989351312">"Configuración de texto a voz"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"Salida de texto a voz"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Velocidad de voz"</string>
@@ -213,7 +213,7 @@
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver y usar los dispositivos disponibles, activa la depuración inalámbrica"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular dispositivo mediante código QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincular dispositivos nuevos mediante escáner de código QR"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo mediante código de sincroniz."</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo con código de sincronización"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincular dispositivos nuevos mediante código de seis dígitos"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos vinculados"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Conectado actualmente"</string>
@@ -235,7 +235,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conéctate a una red Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Acceso directo para informes de errores"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar un botón en el menú de encendido para realizar un informe de errores"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Muestra un botón en el menú de encendido para realizar un informe de errores"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Permanecer activo"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando."</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Registro de Bluetooth HCI"</string>
@@ -331,7 +331,7 @@
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string>
<string name="strict_mode" msgid="889864762140862437">"Modo estricto"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Destello por op. de apps en la conversación principal"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"Destello por op. de apps en el subproceso principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Ubicación del puntero"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"Superponer capa en pant. para mostrar puntos tocados"</string>
<string name="show_touches" msgid="8437666942161289025">"Mostrar presiones"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Debes reiniciar el dispositivo para que se aplique el cambio. Reinícialo ahora o cancela la acción."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 55b5cab..010b85b 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducado"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducada"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
@@ -506,7 +506,7 @@
<string name="alarm_template_far" msgid="6382760514842998629">"Fecha: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que se desactive"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altavoz del teléfono"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Es necesario reiniciar tu dispositivo para que se apliquen los cambios. Reiniciar ahora o cancelar."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 5a11590..ad2a561 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -419,7 +419,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaalia (punane-roheline)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaalia (sinine-kollane)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvide korrigeerimine"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värvikorrigeerimine võimaldab kohandada seadmes kuvatavaid värve"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värvide korrigeerimine võimaldab kohandada seadmes kuvatavaid värve"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Keelatud"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Lubatud"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Selle muudatuse rakendamiseks tuleb seade taaskäivitada. Taaskäivitage kohe või tühistage."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Töö: <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 1aed7e8..1ceb738 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Gaituta"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aldaketa aplikatzeko, berrabiarazi egin behar da gailua. Berrabiaraz ezazu orain, edo utzi bertan behera."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Laneko <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 3b05075..94caa74 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -40,7 +40,7 @@
<item msgid="8339720953594087771">"در حال اتصال به <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="3028983857109369308">"در حال راستیآزمایی با <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="4287401332778341890">"درحال دریافت نشانی IP از <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="1043944043827424501">"متصل شد به <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1043944043827424501">"به <xliff:g id="NETWORK_NAME">%1$s</xliff:g> متصل شد"</item>
<item msgid="7445993821842009653">"معلق"</item>
<item msgid="1175040558087735707">"اتصال قطع شد از <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="699832486578171722">"اتصال قطع شد"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index a46d8cd..d3f1c56 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -94,12 +94,12 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صدای HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صدای HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سمعکها"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"متصل به سمعکها"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"به سمعک متصل شد"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"به رسانه صوتی متصل شد"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"به تلفن صوتی متصل شد"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"به سرور انتقال فایل متصل شد"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"به نقشه متصل شد"</string>
- <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"متصل به SAP"</string>
+ <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"به SAP متصل شد"</string>
<string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"به سرور انتقال فایل متصل نیست"</string>
<string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"به دستگاه ورودی متصل شد"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"برای دسترسی به اینترنت، به دستگاه متصل شد"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غیرفعال"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"برای اعمال این تغییر، دستگاهتان باید راهاندازی مجدد شود. اکنون راهاندازی مجدد کنید یا لغو کنید."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> محل کار"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index af278cb..edfd951 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -156,7 +156,7 @@
<item msgid="5001852592115448348">", aktiivinen (puhelin)"</item>
</string-array>
<string-array name="select_logd_size_titles">
- <item msgid="1191094707770726722">"Ei käytössä"</item>
+ <item msgid="1191094707770726722">"Ei päällä"</item>
<item msgid="7839165897132179888">"64 kt"</item>
<item msgid="2715700596495505626">"256 kt"</item>
<item msgid="7099386891713159947">"1 Mt"</item>
@@ -164,13 +164,13 @@
<item msgid="8243549501764402572">"16 Mt"</item>
</string-array>
<string-array name="select_logd_size_lowram_titles">
- <item msgid="1145807928339101085">"Ei käytössä"</item>
+ <item msgid="1145807928339101085">"Ei päällä"</item>
<item msgid="4064786181089783077">"64 kt"</item>
<item msgid="3052710745383602630">"256 kt"</item>
<item msgid="3691785423374588514">"1 Mt"</item>
</string-array>
<string-array name="select_logd_size_summaries">
- <item msgid="409235464399258501">"Ei käytössä"</item>
+ <item msgid="409235464399258501">"Ei päällä"</item>
<item msgid="4195153527464162486">"64 kt / lokipuskuri"</item>
<item msgid="7464037639415220106">"256 kt / lokipuskuri"</item>
<item msgid="8539423820514360724">"1 Mt / lokipuskuri"</item>
@@ -178,13 +178,13 @@
<item msgid="7892098981256010498">"16 Mt / lokipuskuri"</item>
</string-array>
<string-array name="select_logpersist_titles">
- <item msgid="704720725704372366">"Ei käytössä"</item>
+ <item msgid="704720725704372366">"Ei päällä"</item>
<item msgid="6014837961827347618">"Kaikki"</item>
<item msgid="7387060437894578132">"Kaikki paitsi radio"</item>
<item msgid="7300881231043255746">"vain kernel"</item>
</string-array>
<string-array name="select_logpersist_summaries">
- <item msgid="97587758561106269">"Ei käytössä"</item>
+ <item msgid="97587758561106269">"Ei päällä"</item>
<item msgid="7126170197336963369">"Kaikki lokipuskurit"</item>
<item msgid="7167543126036181392">"Kaikki paitsi radiolokipuskurit"</item>
<item msgid="5135340178556563979">"vain kernel-lokipuskuri"</item>
@@ -247,7 +247,7 @@
<item msgid="5023908510820531131">"Kohteessa <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
- <item msgid="1968128556747588800">"Ei käytössä"</item>
+ <item msgid="1968128556747588800">"Ei päällä"</item>
<item msgid="3033215374382962216">"Näytä päällekkäiset alueet"</item>
<item msgid="3474333938380896988">"Näytä alueet puna-vihersokeille näkyvinä"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 8e82cb2..5ab01c4b 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -153,7 +153,7 @@
<string name="unknown" msgid="3544487229740637809">"Tuntematon"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"Käyttäjä: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"Joitakin oletuksia on asetettu"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"Oletuksia ei asetettu"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"Ei oletuksia valittuina"</string>
<string name="tts_settings" msgid="8130616705989351312">"Tekstistä puheeksi -asetukset"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"Tekstistä puheeksi -toisto"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Puheen nopeus"</string>
@@ -397,7 +397,7 @@
<item msgid="1282170165150762976">"Digitaaliselle sisällölle parhaiten sopivat värit"</item>
</string-array>
<string name="inactive_apps_title" msgid="5372523625297212320">"Valmiustilasovellukset"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Ei käytössä. Ota käyttöön koskettamalla."</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Ei päällä. Ota käyttöön koskettamalla."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktiivinen. Vaihda koskettamalla."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Sovelluksen valmiusluokka: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Käynnissä olevat palvelut"</string>
@@ -533,8 +533,8 @@
<string name="user_add_user_title" msgid="5457079143694924885">"Lisätäänkö uusi käyttäjä?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Voit jakaa tämän laitteen muiden kanssa luomalla lisää käyttäjiä. Kullakin käyttäjällä on oma tilansa, jota he voivat muokata esimerkiksi omilla sovelluksilla ja taustakuvilla. Käyttäjät voivat myös muokata laiteasetuksia, kuten Wi‑Fi-asetuksia, jotka vaikuttavat laitteen kaikkiin käyttäjiin.\n\nKun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia. Esteettömyysominaisuuksia tai ‑palveluita ei välttämättä siirretä uudelle käyttäjälle."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"Määritetäänkö käyttäjän asetukset nyt?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Varmista, että käyttäjä voi vastaanottaa laitteen ja määrittää oman tilansa."</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"Lisätäänkö käyttäjä nyt?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Varmista, että käyttäjä voi ottaa laitteen nyt ja määrittää oman tilansa."</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Määritetäänkö profiilin asetukset nyt?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Määritä nyt"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ei nyt"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ei käytössä"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Käytössä"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peruuta."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (työ)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index a144444..26e5042 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Sélectionnez un profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personnel"</string>
- <string name="category_work" msgid="4014193632325996115">"Travail"</string>
+ <string name="category_work" msgid="4014193632325996115">"Professionnel"</string>
<string name="development_settings_title" msgid="140296922921597393">"Options pour les concepteurs"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les concepteurs"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
@@ -231,7 +231,7 @@
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Échec de l\'association de l\'appareil Soit le code QR est incorrect, soit l\'appareil n\'est pas connecté au même réseau."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresse IP et port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Numériser le code QR"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer un appareil par Wi-Fi en numérisant un code QR"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer l\'appareil par Wi-Fi en numérisant un code QR"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Veuillez vous connecter à un réseau Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, débogage, concepteur"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Raccourci de rapport de bogue"</string>
@@ -496,7 +496,7 @@
<string name="cancel" msgid="5665114069455378395">"Annuler"</string>
<string name="okay" msgid="949938843324579502">"OK"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer la fonction « Ne pas déranger »"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
<string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priorités seulement"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Votre appareil doit être redémarré pour que ce changement prenne effet. Redémarrez-le maintenant ou annulez la modification."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (travail)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index f7bfad8..b8fc50d 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -231,7 +231,7 @@
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Échec de l\'association à l\'appareil. Le code QR est incorrect, ou l\'appareil n\'est pas connecté au même réseau."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresse IP et port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scanner un code QR"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer l\'appareil via le Wi‑Fi à l\'aide d\'un code QR"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associez l\'appareil via le Wi‑Fi à l\'aide d\'un code QR"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Connectez-vous à un réseau Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, débogage, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Raccourci vers rapport de bug"</string>
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée d\'ici <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Désactivé"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Vous devez redémarrer l\'appareil pour que cette modification soit appliquée. Redémarrez maintenant ou annulez l\'opération."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (travail)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 08d2eae..8dc58ef 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -207,7 +207,7 @@
<string name="enable_adb_summary" msgid="3711526030096574316">"Modo de depuración de erros cando o USB está conectado"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"Revogar as autorizacións de depuración por USB"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Depuración sen fíos"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración de erros ao conectarse a wifi"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración de erros ao conectarse á wifi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Produciuse un erro"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración sen fíos"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar os dispositivos dispoñibles, activa a depuración sen fíos"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necesario reiniciar o teu dispositivo para aplicar este cambio. Reiníciao agora ou cancela o cambio."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Aplicación <xliff:g id="APP_NAME">%s</xliff:g> do traballo"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index b88126b..9f69a2c 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -468,7 +468,7 @@
<string name="charge_length_format" msgid="6941645744588690932">"<xliff:g id="ID_1">%1$s</xliff:g> પહેલાં"</string>
<string name="remaining_length_format" msgid="4310625772926171089">"<xliff:g id="ID_1">%1$s</xliff:g> બાકી"</string>
<string name="screen_zoom_summary_small" msgid="6050633151263074260">"નાનું"</string>
- <string name="screen_zoom_summary_default" msgid="1888865694033865408">"ડિફોલ્ટ"</string>
+ <string name="screen_zoom_summary_default" msgid="1888865694033865408">"ડિફૉલ્ટ"</string>
<string name="screen_zoom_summary_large" msgid="4706951482598978984">"મોટું"</string>
<string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"વધુ મોટું"</string>
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"સૌથી મોટું"</string>
@@ -534,7 +534,7 @@
<string name="user_add_user_message_long" msgid="1527434966294733380">"તમે વધારાના વપરાશકર્તાઓ બનાવીને અન્ય લોકો સાથે આ ડિવાઇસને શેર કરી શકો છો. દરેક વપરાશકર્તા પાસે તેમની પોતાની સ્પેસ છે, જેને તેઓ ઍપ, વૉલપેપર, વગેરે સાથે કસ્ટમાઇઝ કરી શકે છે. વપરાશકર્તાઓ પ્રત્યેક વ્યક્તિને અસર કરતી હોય તેવી ડિવાઇસ સેટિંગ જેમ કે વાઇ-ફાઇને પણ સમાયોજિત કરી શકે છે.\n\nજ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમની સ્પેસ સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે. નવા વપરાશકર્તાને ઍક્સેસિબિલિટી સેટિંગ અને સેવાઓ ટ્રાન્સફર ન પણ થાય."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ અપ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે એપ્લિકેશન્સને અપડેટ કરી શકે છે."</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"અત્યારે જ વપરાશકર્તાને સેટ અપ કરીએ?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"ખાતરી કરો કે વ્યક્તિ ઉપકરણ લેવા અને તેમના સ્થાનનું સેટ અપ કરવા માટે ઉપલબ્ધ છે"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"ખાતરી કરો કે વ્યક્તિ ડિવાઇસ લેવા અને તેમના સ્થાનનું સેટ અપ કરવા માટે ઉપલબ્ધ છે"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"હવે પ્રોફાઇલ સેટ કરીએ?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"હવે સેટ કરો"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"હમણાં નહીં"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string>
<string name="guest_nickname" msgid="6332276931583337261">"અતિથિ"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ડિવાઇસ ડિફૉલ્ટ"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"બંધ છે"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ચાલુ છે"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"આ ફેરફારને લાગુ કરવા માટે તમારા ડિવાઇસને રીબૂટ કરવાની જરૂર છે. હમણાં જ રીબૂટ કરો કે રદ કરો."</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ઑફિસ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7dda73d..dc8e28b 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -284,7 +284,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"बैटरी की खपत कम और नेटवर्क की परफ़ॉर्मेंस बेहतर होती है"</string>
- <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"जब यह मोड चालू होता है, तब नेटवर्क से कनेक्ट होने पर हर बार इस डिवाइस का MAC पता बदल सकता है. ऐसा तब होता है, जब डिवाइस किसी ऐसे नेटवर्क से जुड़ता है जिस पर MAC पते को बिना किसी तय नियम के बदलने की सुविधा चालू होती है."</string>
+ <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"जब यह मोड चालू होता है, तब नेटवर्क से कनेक्ट होने पर हर बार इस डिवाइस का मैक पता बदल सकता है. ऐसा तब होता है, जब डिवाइस किसी ऐसे नेटवर्क से जुड़ता है जिस पर मैक पते को बिना किसी तय नियम के बदलने की सुविधा चालू होती है."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"लॉगर बफ़र आकार"</string>
@@ -418,7 +418,7 @@
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"लाल-हरे रंग की पहचान न कर पाना (लाल-हरा)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"लाल रंग पहचान न पाना (लाल-हरा)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"नीला रंग पहचान न पाना (नीला-पीला)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"रंग सुधार"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"रंग में सुधार करने की सुविधा"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"रंग में सुधार करने की सुविधा, आपके डिवाइस पर दिखने वाले रंगों में बदलाव करने में मदद करती है"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"बंद है"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"चालू है"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"बदली गई सेटिंग को लागू करने के लिए, अपने डिवाइस को फिर से चालू करें. डिवाइस को फिर से चालू करें या रद्द करें."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ऑफ़िस वाला <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 1db40a8..f887839 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -251,7 +251,7 @@
<string name="wifi_display_certification" msgid="1805579519992520381">"Certifikacija bežičnog prikaza"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući opširnu prijavu na Wi-Fi"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje traženja Wi-Fija"</string>
- <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasum. odabir MAC-a poboljšan Wi‑Fi‑jem"</string>
+ <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasum. odabir MAC-a poboljšan Wi‑Fijem"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci uvijek aktivni"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje za modemsko povezivanje"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -534,8 +534,8 @@
<string name="user_add_user_title" msgid="5457079143694924885">"Dodati novog korisnika?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Da biste ovaj uređaj dijelili s drugima, možete napraviti dodatne korisnike. Svaki korisnik ima svoj prostor koji može prilagoditi pomoću vlastitih aplikacija, pozadine i tako dalje. Korisnici mogu prilagoditi i postavke uređaja koje utječu na sve ostale korisnike, na primjer Wi‑Fi.\n\nKada dodate novog korisnika, ta osoba mora postaviti svoj prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike. Postavke i usluge pristupačnosti možda se neće prenijeti na novog korisnika."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"Postaviti korisnika sada?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Provjerite može li osoba uzeti uređaj i postaviti svoj prostor"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"Želite li postaviti korisnika?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Uređaj morate dati toj osobi da sama postavi svoj prostor"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li sada postaviti profil?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Postavi sada"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ne sad"</string>
@@ -555,4 +555,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Uređaj se mora ponovno pokrenuti da bi se ta promjena primijenila. Ponovo pokrenite uređaj odmah ili odustanite."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 4b2132b..d7d2694 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet a következő időpontig: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Letiltva"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Engedélyezve"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Az eszközt újra kell indítani, hogy a módosítás megtörténjen. Indítsa újra most, vagy vesse el a módosítást."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Munkahelyi <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 11da054..a5ef6b5 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Լիցքը (<xliff:g id="LEVEL">%2$s</xliff:g>) պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Լիցքը պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Մարտկոցի լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -452,7 +452,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Դանդաղ լիցքավորում"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Չի լիցքավորվում"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Միացված է հոսանքի աղբյուրին, սակայն այս պահին չի կարող լիցքավորվել"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Միացված է հոսանքին, այս պահին չի կարող լիցքավորվել"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"Լիցքավորված է"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
<string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Անջատված է"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Միացված է"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Սարքն անհրաժեշտ է վերագործարկել, որպեսզի փոփոխությունը կիրառվի։ Վերագործարկեք հիմա կամ չեղարկեք փոփոխությունը։"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Աշխատանքային <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3b02fbf..04ca2f6 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Pilih profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Pribadi"</string>
- <string name="category_work" msgid="4014193632325996115">"Kantor"</string>
+ <string name="category_work" msgid="4014193632325996115">"Kerja"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opsi developer"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Aktifkan opsi developer"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Menyetel opsi untuk pengembangan apl"</string>
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterai mungkin habis pada <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterai mungkin habis pada pukul <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tersisa lebih dari <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Nonaktif"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktif"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Perangkat Anda harus di-reboot agar perubahan ini diterapkan. Reboot sekarang atau batalkan."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> kerja"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 6560de0..ce60eb5 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slökkt"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Virkt"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Endurræsa þarf tækið til að þessi breyting taki gildi. Endurræstu núna eða hættu við."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> í vinnu"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index ece0ba4..bef644b 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Non attivo"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Attivo"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Devi riavviare il dispositivo per applicare questa modifica. Riavvia ora o annulla."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> di lavoro"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 23e701d..ed79632 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"מושבת"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> של עבודה"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 7640722..3f08a6a 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -210,7 +210,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi 接続時にデバッグモード"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"エラー"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"ワイヤレス デバッグ"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"利用可能なデバイスを確認して使用するには、ワイヤレス デバッグをオンにしてください"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"利用可能なデバイスを確認して使用するには、ワイヤレス デバッグを ON にしてください"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR コードによるデバイスのペア設定"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR コードスキャナを使って新しいデバイスをペア設定します"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"ペア設定コードによるデバイスのペア設定"</string>
@@ -235,7 +235,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi ネットワークに接続してください"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, デバッグ, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"バグレポートのショートカット"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源メニューにバグレポートを取得するボタンを表示する"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源ボタン メニューにバグレポートを取得するボタンを表示する"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"スリープモードにしない"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"充電中に画面をスリープにしない"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI スヌープログ"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"無効"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"有効"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"この変更を適用するには、デバイスの再起動が必要です。今すぐ再起動してください。キャンセルすることもできます。"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"仕事の<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 985188f..2ebc3ee 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ჩართული"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ამ ცვლილების ასამოქმედებლად თქვენი მოწყობილობა უნდა გადაიტვირთოს. გადატვირთეთ ახლავე ან გააუქმეთ."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"სამსახურის <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a5308e4..91e5488 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -42,7 +42,7 @@
<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>
<string name="tap_to_sign_up" msgid="5356397741063740395">"Тіркелу үшін түртіңіз."</string>
- <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернетпен байланыс жоқ."</string>
+ <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернетпен байланыс жоқ"</string>
<string name="private_dns_broken" msgid="1984159464346556931">"Жеке DNS серверіне кіру мүмкін емес."</string>
<string name="wifi_limited_connection" msgid="1184778285475204682">"Шектеулі байланыс"</string>
<string name="wifi_status_no_internet" msgid="3799933875988829048">"Интернетпен байланыс жоқ"</string>
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Орташа"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Жылдам"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Өте жылдам"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті."</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылған"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылуда…"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өшірулі"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (жұмыс)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 0ff48e1..143f5f9 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -445,8 +445,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបត្រូវសាក"</string>
- <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបត្រូវសាក"</string>
+ <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
+ <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"មិនស្គាល់"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"កំពុងបញ្ចូលថ្ម"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
@@ -537,7 +537,7 @@
<string name="user_setup_dialog_message" msgid="269931619868102841">"សូមប្រាកដថាអ្នកប្រើប្រាស់នេះអាចយកឧបករណ៍ និងរៀបចំទំហំផ្ទុករបស់គេបាន"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"រៀបចំប្រវត្តិរូបឥឡូវ?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"រៀបចំឥឡូវ"</string>
- <string name="user_setup_button_setup_later" msgid="8712980133555493516">"កុំអាល"</string>
+ <string name="user_setup_button_setup_later" msgid="8712980133555493516">"កុំទាន់"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"បន្ថែម"</string>
<string name="user_new_user_name" msgid="60979820612818840">"អ្នកប្រើថ្មី"</string>
<string name="user_new_profile_name" msgid="2405500423304678841">"ប្រវត្តិរូបថ្មី"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"បានបិទ"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"បានបើក"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ត្រូវតែចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ ទើបការផ្លាស់ប្ដូរនេះត្រូវបានអនុវត្ត។ ចាប់ផ្ដើមឡើងវិញឥឡូវនេះ ឬបោះបង់។"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> សម្រាប់ការងារ"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 52e3b99..1df141c 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ಸಾಧನದ ಡೀಫಾಲ್ಟ್"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ."</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ಉದ್ಯೋಗ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index b8d587b..86e1650 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -495,7 +495,7 @@
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"시간 줄이기"</string>
<string name="cancel" msgid="5665114069455378395">"취소"</string>
<string name="okay" msgid="949938843324579502">"확인"</string>
- <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"켜기"</string>
+ <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"사용 안함"</string>
<string name="zen_interruption_level_priority" msgid="5392140786447823299">"중요 알림만 허용"</string>
@@ -530,7 +530,7 @@
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"내 계정의 앱 및 콘텐츠에 대한 액세스를 제한할 수 있습니다."</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"사용자"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"제한된 프로필"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"새 사용자를 추가할까요?"</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"신규 사용자를 추가할까요?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"추가 사용자를 만들어 다른 사용자와 기기를 공유할 수 있습니다. 각 사용자는 앱, 배경화면 등으로 맞춤설정할 수 있는 자신만의 공간을 갖게 됩니다. 또한 모든 사용자에게 영향을 미치는 Wi‑Fi와 같은 기기 설정도 조정할 수 있습니다.\n\n추가된 신규 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자가 앱을 업데이트할 수 있으며, 업데이트는 다른 사용자에게도 적용됩니다. 접근성 설정 및 서비스는 신규 사용자에게 이전되지 않을 수도 있습니다."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"지금 사용자를 설정하시겠습니까?"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"사용 중지됨"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"사용 설정됨"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"변경사항을 적용하려면 기기를 재부팅해야 합니다. 지금 재부팅하거나 취소하세요."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"직장용 <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 3c57c79..925f4a7 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -224,7 +224,7 @@
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> туура тармакка туташып турганын текшериңиз"</string>
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Түзмөктү жупташтыруу"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi жупташтыруучу коду"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Жупташтырылган жок"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Туташкан жок"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Түзмөк бир тармакка туташып турушу керек."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Түзмөк жупташтырылууда…"</string>
@@ -302,7 +302,7 @@
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Мүмкүнчүлүккө жараша, модем режиминде аппарат тезирээк иштей баштайт"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB аркылуу жөндөөгө уруксат бересизби?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB-жөндөө - өндүрүү максатында гана түзүлгөн. Аны компүтериңиз менен түзмөгүңүздүн ортосунда берилиштерди алмашуу, түзмөгүңүзгө колдонмолорду эскертүүсүз орнотуу жана лог берилиштерин окуу үчүн колдонсоңуз болот."</string>
- <string name="adbwifi_warning_title" msgid="727104571653031865">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилсинби?"</string>
+ <string name="adbwifi_warning_title" msgid="727104571653031865">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат бересизби?"</string>
<string name="adbwifi_warning_message" msgid="8005936574322702388">"Мүчүлүштүктөрдү Wi-Fi аркылуу аныктоо – өндүрүү максатында гана түзүлгөн. Аны компьютериңиз менен түзмөгүңүздүн ортосунда маалыматты алмашуу, колдонмолорду түзмөгүңүзгө эскертүүсүз орнотуу жана маалыматтар таржымалын окуу үчүн колдонсоңуз болот."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Сиз мурун USB жөндөөлөрүнө уруксат берген бардык компүтерлердин жеткиси жокко чыгарылсынбы?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Жөндөөлөрдү өзгөртүү"</string>
@@ -445,8 +445,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Планшет бир аздан кийин өчүп калышы мүмкүн (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Түзмөк бир аздан кийин өчүп калышы мүмкүн (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> кийин кубатталат"</string>
- <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> кийин кубатталат"</string>
+ <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> кийин толук кубатталып бүтөт"</string>
+ <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталып бүтөт"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Кубатталууда"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өчүк"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөртүүнү колдонуу үчүн түзмөктү өчүрүп күйгүзүңүз. Азыр өчүрүп күйгүзүңүз же жокко чыгарыңыз."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Жумуш <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 02f73b5..3bf1996 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ເປີດການນຳໃຊ້ແລ້ວ"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ທ່ານຕ້ອງປິດເປີດອຸປະກອນຄືນໃໝ່ເພື່ອນຳໃຊ້ການປ່ຽນແປງນີ້. ປິດເປີດໃໝ່ດຽວນີ້ ຫຼື ຍົກເລີກ."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ບ່ອນເຮັດວຽກ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index dc6347a..153c995 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Išjungta"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Įgalinta"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kad pakeitimas būtų pritaikytas, įrenginį reikia paleisti iš naujo. Dabar paleiskite iš naujo arba atšaukite."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Darbo „<xliff:g id="APP_NAME">%s</xliff:g>“"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 0a185d0..f6e7f35 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -168,7 +168,7 @@
<string name="tts_play_example_summary" msgid="634044730710636383">"Atskaņot īsu runas sintēzes demonstrāciju"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"Instalēt balss datus"</string>
<string name="tts_install_data_summary" msgid="3608874324992243851">"Instalēt runas sintēzei nepieciešamos balss datus"</string>
- <string name="tts_engine_security_warning" msgid="3372432853837988146">"Lietojot šo runas sintēzes programmu, var tikt apkopots viss ierunātais teksts, tostarp tāda personīgā informācija kā paroles un kredītkaršu numuri. Tā ir no <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> programmas. Vai iespējot šīs runas sintēzes programmas lietošanu?"</string>
+ <string name="tts_engine_security_warning" msgid="3372432853837988146">"Lietojot šo runas sintēzes programmu, var tikt vākts viss ierunātais teksts, tostarp tāda personīgā informācija kā paroles un kredītkaršu numuri. Tā ir no <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> programmas. Vai iespējot šīs runas sintēzes programmas lietošanu?"</string>
<string name="tts_engine_network_required" msgid="8722087649733906851">"Lai izmantotu teksta pārveidošanu runā šajā valodā, ir nepieciešams aktīvs tīkla savienojums."</string>
<string name="tts_default_sample_string" msgid="6388016028292967973">"Šis ir runas sintēzes piemērs."</string>
<string name="tts_status_title" msgid="8190784181389278640">"Noklusējuma valodas statuss"</string>
@@ -554,6 +554,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Atspējots"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Iespējots"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Lai šīs izmaiņas tiktu piemērotas, nepieciešama ierīces atkārtota palaišana. Atkārtoti palaidiet to tūlīt vai atceliet izmaiņas."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Darbā: <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index e0cc38d..d55f1af 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Оневозможено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Овозможено"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да се примени променава, уредот мора да се рестартира. Рестартирајте сега или откажете."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Работна <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 1a3f068..c5267d6 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
<string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ഉപകരണത്തിന്റെ ഡിഫോൾട്ട് പ്രവർത്തനം"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക."</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ഔദ്യോഗികം <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index a342862..0a01f84 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -419,7 +419,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномаль (улаан-ногоон)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомаль (цэнхэр-шар)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Өнгө тохируулах"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Өнгө залруулга нь төхөөрөмж дээрээ өнгийг хэрхэн үзүүлэхийг тохируулах боломжийг танд олгодог"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Өнгө тохируулга нь танд төхөөрөмж дээрээ өнгө хэрхэн харагдахыг тохируулах боломжийг олгодог"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Идэвхгүй болгосон"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Идэвхжүүлсэн"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Энэ өөрчлөлтийг хэрэгжүүлэхийн тулд таны төхөөрөмжийг дахин асаах ёстой. Одоо дахин асаах эсвэл болино уу."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ажлын <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 0895cd4..075c748 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -243,7 +243,7 @@
<string name="oem_unlock_enable" msgid="5334869171871566731">"OEM अनलॉक करणे"</string>
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"बूटलोडर अनलॉक करण्यासाठी अनुमती द्या"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM अनलॉक करण्यास अनुमती द्यायची?"</string>
- <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"चेतावणी: हे सेटिंग चालू असताना या डिव्हाइस वर डिव्हाइस संरक्षण वैशिष्ट्ये काम करणार नाहीत."</string>
+ <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"चेतावणी: हे सेटिंग सुरू असताना या डिव्हाइस वर डिव्हाइस संरक्षण वैशिष्ट्ये काम करणार नाहीत."</string>
<string name="mock_location_app" msgid="6269380172542248304">"बनावट स्थान अॅप निवडा"</string>
<string name="mock_location_app_not_set" msgid="6972032787262831155">"कोणताही बनावट स्थान अॅप सेट केला नाही"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"बनावट स्थान अॅप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -298,7 +298,7 @@
<string name="allow_mock_location" msgid="2102650981552527884">"बनावट स्थानांना अनुमती द्या"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"बनावट स्थानांना अनुमती द्या"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"दृश्य विशेषता तपासणी सुरू करा"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"वाय-फाय चालू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"वाय-फाय सुरू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"उपलब्ध असल्यास टेदरिंग हार्डवेअर ॲक्सिलरेशन वापरा"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB डीबग करण्यास अनुमती द्यायची?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string>
@@ -409,7 +409,7 @@
<string name="convert_to_file_encryption_enabled" msgid="840757431284311754">"रूपांतरित करा..."</string>
<string name="convert_to_file_encryption_done" msgid="8965831011811180627">"फाईल आधीपासून एंक्रिप्ट होती"</string>
<string name="title_convert_fbe" msgid="5780013350366495149">"फाईल आधारित कूटबद्धीकरणावर रूपांतरित करणे"</string>
- <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरु ठेवण्यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string>
+ <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरू ठेवण्यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string>
<string name="button_convert_fbe" msgid="1159861795137727671">"पुसा आणि रुपांतरित करा..."</string>
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रंग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB वापरा"</string>
@@ -495,8 +495,8 @@
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"कमी वेळ."</string>
<string name="cancel" msgid="5665114069455378395">"रद्द करा"</string>
<string name="okay" msgid="949938843324579502">"ठीक आहे"</string>
- <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करा"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका चालू करा"</string>
+ <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कधीही नाही"</string>
<string name="zen_interruption_level_priority" msgid="5392140786447823299">"केवळ प्राधान्य"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
<string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"डिव्हाइस डीफॉल्ट"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"बंद केले आहे"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सुरू केले आहे"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"हा बदल लागू करण्यासाठी तुमचे डिव्हाइस रीबूट करणे आवश्यक आहे. आता रीबूट करा किंवा रद्द करा."</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"कार्य <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index a1c6782..cdf32a7 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Dilumpuhkan"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Didayakan"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Peranti anda mesti dibut semula supaya perubahan ini berlaku. But semula sekarang atau batalkan."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Kerja <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 0edc100..2bd3b45 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -153,7 +153,7 @@
<string name="unknown" msgid="3544487229740637809">"မသိ"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"အသုံးပြုသူ- <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"ပုံမှန်သတ်မှတ်ထားခြင်းမရှိ"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"မူရင်း သတ်မှတ်မထားပါ။"</string>
<string name="tts_settings" msgid="8130616705989351312">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"စာသားမှ စကားပြောသို့ အထွက်"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"စကားပြောနှုန်း"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ပိတ်ထားသည်"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ဖွင့်ထားသည်"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ဤအပြောင်းအလဲ ထည့်သွင်းရန် သင့်စက်ကို ပြန်လည်စတင်ရမည်။ ယခု ပြန်လည်စတင်ပါ သို့မဟုတ် ပယ်ဖျက်ပါ။"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"အလုပ် <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d683070..de5bed6 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slått av"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Jobb-<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index ee22c60..bfe295a 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -399,7 +399,7 @@
<string name="inactive_apps_title" msgid="5372523625297212320">"स्ट्यान्डबाई एपहरू"</string>
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"निष्क्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"सक्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string>
- <string name="standby_bucket_summary" msgid="5128193447550429600">"अनुप्रयोगको स्ट्यान्डबाई अवस्था:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
+ <string name="standby_bucket_summary" msgid="5128193447550429600">"एपको स्ट्यान्डबाई अवस्था:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"चलिरहेका सेवाहरू"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"हाल चालु भइरहेका सेवाहरू हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string>
<string name="guest_nickname" msgid="6332276931583337261">"अतिथि"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"पूर्वनिर्धारित यन्त्र"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"असक्षम पारिएको छ"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"कार्यालयको प्रोफाइल <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index dc5f8f2..a822719 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ingeschakeld"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> voor werk"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 18cc9e3..ab9fbc3 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -235,7 +235,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ଦୟାକରି ଏକ ୱାଇ-ଫାଇ ନେଟୱାର୍କରେ ସଂଯୋଗ କରନ୍ତୁ"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ଡିବଗ୍, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"ବଗ୍ ରିପୋର୍ଟ ସର୍ଟକଟ୍"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ବଗ୍ ରିପୋର୍ଟ ଦେବାପାଇଁ ପାୱାର୍ ମେନୁରେ ଏକ ବଟନ୍ ଦେଖନ୍ତୁ"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ବଗ୍ ରିପୋର୍ଟ ଦେବା ପାଇଁ ପାୱାର୍ ମେନୁରେ ଏକ ବଟନ୍ ଦେଖାନ୍ତୁ"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"ଜାଗ୍ରତ ରଖନ୍ତୁ"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"ବ୍ଲୁଟୂଥ୍ HCI ସ୍ନୁପ୍ ଲଗ୍ ସକ୍ଷମ କରନ୍ତୁ"</string>
@@ -245,7 +245,7 @@
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM ଅନଲକ୍ କରିବା ଅନୁମତି ଦେବେ?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ଚେତାବନୀ: ଏହି ସେଟିଙ୍ଗ ଚାଲୁ ଥିବାବେଳେ ଡିଭାଇସ୍ର ସୁରକ୍ଷା ବୈଶିଷ୍ଟ୍ୟ କାମ କରିବ ନାହିଁ"</string>
<string name="mock_location_app" msgid="6269380172542248304">"ମକ୍ ଲୋକେସନ୍ ଆପ୍ର ଚୟନ କରନ୍ତୁ"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"କୌଣସି ନକଲି ଲୋକେଶନ ଆପ୍ ସେଟ୍ କରାଯାଇନାହିଁ"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"କୌଣସି ମକ୍ ଲୋକେସନ ଆପ୍ ସେଟ୍ କରାଯାଇନାହିଁ"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"ମକ୍ ଲୋକେସନ୍ ଆପ୍: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"ନେଟ୍ୱର୍କିଙ୍ଗ"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ଅତିଥି"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ୱାର୍କ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index b502f3f..35d8cba 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ਮਹਿਮਾਨ"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਡੀਵਾਈਸ"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ਇਸ ਤਬਦੀਲੀ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਰੀਬੂਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। ਹੁਣੇ ਰੀਬੂਟ ਕਰੋ ਜਾਂ ਰੱਦ ਕਰੋ।"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ਕੰਮ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 8a29bf0..54ed131 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Osobiste"</string>
- <string name="category_work" msgid="4014193632325996115">"Do pracy"</string>
+ <string name="category_work" msgid="4014193632325996115">"Służbowe"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opcje programistyczne"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje dla programistów"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string>
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Wyłączono"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Włączono"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Wprowadzenie zmiany wymaga ponownego uruchomienia urządzenia. Uruchom ponownie teraz lub anuluj."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (do pracy)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 58a13cd..c6dc1d3 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index ca85151..999e684 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -212,9 +212,9 @@
<string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração sem fios"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e utilizar dispositivos disponíveis, ative a depuração sem fios."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Sincronize o dispositivo com o código QR"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sincronize novos dispositivos com o leitor de códigos QR."</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sincroniza novos dispositivos com o leitor de códigos QR."</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Sincronize dispositivo com código de sincronização"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Sincronize novos dispositivos através do código de seis dígitos."</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Sincroniza novos dispositivos através do código de seis dígitos."</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos sincronizados"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Atualmente ligado."</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Detalhes do dispositivo"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativada"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para aplicar esta alteração. Reinicie agora ou cancele."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 58a13cd..c6dc1d3 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
@@ -554,4 +554,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index f967c8c..ba2f36f 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -554,6 +554,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Dezactivat"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pentru ca modificarea să se aplice, trebuie să reporniți dispozitivul. Reporniți-l acum sau anulați."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de serviciu"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index e41b3b7..8ec3875 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -210,7 +210,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим отладки при подключении к сети Wi‑Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Ошибка"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Отладка по Wi-Fi"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Чтобы посмотреть и использовать доступные устройства, включите отладку по Wi-Fi"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Чтобы увидеть и использовать доступные устройства, включите отладку по Wi-Fi."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Подключить устройство с помощью QR-кода"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Подключение новых устройств с помощью сканера QR-кодов"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Подключить устройство с помощью кода подключения"</string>
@@ -223,7 +223,7 @@
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Не удалось установить подключение"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Убедитесь, что устройство \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" подключено к нужной сети."</string>
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Подключение к устройству"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код подключения к сети Wi‑Fi"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код подключения по сети Wi‑Fi"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Не удалось подключить устройство"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Устройство должно быть подключено к той же самой сети."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string>
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Отключено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Включено"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Чтобы изменение вступило в силу, необходимо перезапустить устройство. Вы можете сделать это сейчас или позже."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Рабочее приложение \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 5710985..01c3634 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"අබල කළා"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"සබලයි"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"මෙම වෙනස යෙදීමට ඔබේ උපාංගය නැවත පණ ගැන්විය යුතුය. දැන් නැවත පණ ගන්වන්න හෝ අවලංගු කරන්න."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"කාර්යාල <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index b3848a9..b5cbf43 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Stredná"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rýchla"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi rýchla"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnosť vypršala"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vypršalo"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojený"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prebieha odpájanie..."</string>
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Výber profilu"</string>
<string name="category_personal" msgid="6236798763159385225">"Osobné"</string>
- <string name="category_work" msgid="4014193632325996115">"Práca"</string>
+ <string name="category_work" msgid="4014193632325996115">"Pracovné"</string>
<string name="development_settings_title" msgid="140296922921597393">"Pre vývojárov"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Povolenie možností vývojára"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Možnosti nastavenia vývoja aplikácií"</string>
@@ -508,7 +508,7 @@
<string name="alarm_template_far" msgid="6382760514842998629">"o <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvanie"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vždy sa opýtať"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"Dokiaľ túto funkciu nevypnete"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"Dokým funkciu nevypnete"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Teraz"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Reproduktor telefónu"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuté"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuté"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Táto zmena sa uplatní až po reštartovaní zariadenia. Zariadenie reštartujte alebo zmenu zrušte."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Pracovná aplikácia <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 658c192..86cccb8 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -214,7 +214,7 @@
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Seznanjanje naprave s kodo QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Seznanitev novih naprav z optičnim bralnikom kod QR"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Seznanjanje naprave s kodo za seznanjanje"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Seznanjanje novih naprav s šestmestno kodo"</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Seznanitev novih naprav s šestmestno kodo"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Seznanjene naprave"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Trenutno povezano"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Podrobnosti o napravi"</string>
@@ -509,7 +509,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vedno vprašaj"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dokler ne izklopite"</string>
- <string name="time_unit_just_now" msgid="3006134267292728099">"pravkar"</string>
+ <string name="time_unit_just_now" msgid="3006134267292728099">"Pravkar"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Zvočnik telefona"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string>
@@ -556,4 +556,6 @@
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogočeno"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Napravo je treba znova zagnati, da bo ta sprememba uveljavljena. Znova zaženite zdaj ali prekličite."</string>
<string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za delo"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 17d2d50..bd3353c 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -207,7 +207,7 @@
<string name="enable_adb_summary" msgid="3711526030096574316">"Korrigjo gabimet e modalitetit kur UBS-ja është e lidhur"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"Anulo autorizimet e korrigjimeve të gabimeve të USB-së"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Korrigjimi përmes Wi-Fi"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Regjimi i korrigjimit kur Wi‑Fi është i lidhur"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modaliteti i korrigjimit kur Wi‑Fi është i lidhur"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Gabim"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Korrigjimi përmes Wi-Fi"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Për të parë dhe përdorur pajisjet e disponueshme, aktivizo korrigjimin përmes Wi-Fi"</string>
@@ -446,7 +446,7 @@
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Pajisja mund të fiket së shpejti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në karikim"</string>
- <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të karikohen"</string>
+ <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të karikohet"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Joaktiv"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pajisja jote duhet të riniset që ky ndryshim të zbatohet. Rinise tani ose anuloje."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> për punën"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e0a7d0b..29f23b4 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -554,6 +554,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Онемогућено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> за посао"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f6745b2..a40100e 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -183,19 +183,19 @@
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Återställ tonhöjden för tal"</string>
<string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Återställ tonhöjden för talad text till standardinställningen."</string>
<string-array name="tts_rate_entries">
- <item msgid="9004239613505400644">"Mycket långsamt"</item>
- <item msgid="1815382991399815061">"Långsamt"</item>
- <item msgid="3075292553049300105">"Normalt"</item>
- <item msgid="1158955023692670059">"Snabbt"</item>
+ <item msgid="9004239613505400644">"Mycket långsam"</item>
+ <item msgid="1815382991399815061">"Långsam"</item>
+ <item msgid="3075292553049300105">"Normal"</item>
+ <item msgid="1158955023692670059">"Snabb"</item>
<item msgid="5664310435707146591">"Snabbare"</item>
- <item msgid="5491266922147715962">"Mycket snabbt"</item>
- <item msgid="7659240015901486196">"Supersnabbt"</item>
- <item msgid="7147051179282410945">"Turbosnabbt"</item>
+ <item msgid="5491266922147715962">"Mycket snabb"</item>
+ <item msgid="7659240015901486196">"Supersnabb"</item>
+ <item msgid="7147051179282410945">"Turbosnabb"</item>
<item msgid="581904787661470707">"Snabbast"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Välj profil"</string>
- <string name="category_personal" msgid="6236798763159385225">"Personligt"</string>
- <string name="category_work" msgid="4014193632325996115">"Arbetet"</string>
+ <string name="category_personal" msgid="6236798763159385225">"Privat"</string>
+ <string name="category_work" msgid="4014193632325996115">"Jobb"</string>
<string name="development_settings_title" msgid="140296922921597393">"Utvecklaralternativ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Aktivera utvecklaralternativ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ange alternativ för apputveckling"</string>
@@ -213,9 +213,9 @@
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Aktivera trådlös felsökning om du vill se tillgängliga enheter"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parkoppla enheten med en QR-kod"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parkoppla nya enheter med QR-kodsläsare"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Koppla enheten med en kopplingskod"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Koppla nya enheter med en sexsiffrig kod"</string>
- <string name="adb_paired_devices_title" msgid="5268997341526217362">"Kopplade enheter"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parkoppla enheten med en parkopplingskod"</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Parkoppla nya enheter med en sexsiffrig kod"</string>
+ <string name="adb_paired_devices_title" msgid="5268997341526217362">"Parkopplade enheter"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Anslutna just nu"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Enhetsinformation"</string>
<string name="adb_device_forget" msgid="193072400783068417">"Glöm"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inaktiverat"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiverat"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten måste startas om för att ändringen ska börja gälla. Starta om nu eller avbryt."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> för arbetet"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index a29b74e..af39356 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -40,7 +40,7 @@
<item msgid="8339720953594087771">"Inaunganisha kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="3028983857109369308">"Uhalalishaji kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="4287401332778341890">"Inamiliki anwani ya IP kutoka <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="1043944043827424501">" Umeunganishwa kwa<xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1043944043827424501">"Umeunganishwa kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
<item msgid="7445993821842009653">"Imesimamishwa"</item>
<item msgid="1175040558087735707">"inakatisha muunganisho kutoka <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="699832486578171722">"Muunganisho Umekatika"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 7df39d5..fedf1c85 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Chagua wasifu"</string>
<string name="category_personal" msgid="6236798763159385225">"Ya Kibinafsi"</string>
- <string name="category_work" msgid="4014193632325996115">"Kazini"</string>
+ <string name="category_work" msgid="4014193632325996115">"Ya Kazini"</string>
<string name="development_settings_title" msgid="140296922921597393">"Chaguo za wasanidi"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Washa chaguo za wasanidi programu"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Weka chaguo kwa ajili ya maendeleo ya programu"</string>
@@ -485,7 +485,7 @@
<string name="ims_reg_title" msgid="8197592958123671062">"Hali ya usajili wa IMS"</string>
<string name="ims_reg_status_registered" msgid="884916398194885457">"Imesajiliwa"</string>
<string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Haijasajiliwa"</string>
- <string name="status_unavailable" msgid="5279036186589861608">"Haipatikani"</string>
+ <string name="status_unavailable" msgid="5279036186589861608">"Hamna"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"Imechagua anwani ya MAC kwa nasibu"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="other">Imeunganisha vifaa %1$d</item>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Imezimwa"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ya kazini <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index fa922ea..345f0a7 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"முடக்கப்பட்டது"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"இயக்கப்பட்டது"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"இந்த மாற்றங்கள் செயல்படுத்தப்பட உங்கள் சாதனத்தை மறுபடி தொடங்க வேண்டும். இப்போதே மறுபடி தொடங்கவும் அல்லது ரத்துசெய்யவும்."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"பணியிடம் <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 0e36c5f..c4fda01 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -153,9 +153,9 @@
<string name="unknown" msgid="3544487229740637809">"తెలియదు"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"వినియోగదారు: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"కొన్ని డిఫాల్ట్లు సెట్ చేయబడ్డాయి"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్షన్లు వేటినీ సెట్ చేయలేదు"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్షన్లు ఏవీ సెట్ చేయలేదు"</string>
<string name="tts_settings" msgid="8130616705989351312">"వచనం నుండి ప్రసంగం సెట్టింగ్లు"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"వచనం నుండి మాట అవుట్పుట్"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"టెక్స్ట్-టు-స్పీచ్ అవుట్పుట్"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"ప్రసంగం రేట్"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"వచనాన్ని చదివి వినిపించాల్సిన వేగం"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"పిచ్"</string>
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్ను ఎంచుకోండి"</string>
<string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
- <string name="category_work" msgid="4014193632325996115">"కార్యాలయం"</string>
+ <string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
<string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఎంపికలు"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"అనువర్తన అభివృద్ధి కోసం ఎంపికలను సెట్ చేయండి"</string>
@@ -229,7 +229,7 @@
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR కోడ్ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"పరికరం పెయిర్ చేయబడుతోంది…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"పరికరాన్ని పెయిర్ చేయడం విఫలమైంది. QR కోడ్ తప్పుగా ఉండడం గాని, లేదా పరికరం అదే నెట్వర్క్కు కనెక్ట్ అయి లేకపోవడం గాని జరిగింది."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP చిరునామా & పోర్ట్"</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP అడ్రస్ & పోర్ట్"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR కోడ్ను స్కాన్ చేయండి"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR కోడ్ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"దయచేసి Wi-Fi నెట్వర్క్కు కనెక్ట్ చేయండి"</string>
@@ -418,8 +418,8 @@
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"డ్యూటెరానోమలీ (ఎరుపు-ఆకుపచ్చ)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ప్రొటానోమలీ (ఎరుపు-ఆకుపచ్చ రంగు)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ట్రైటనోమలీ (నీలం-పసుపు రంగు)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"రంగు సవరణ"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"రంగులు సరి చేసే ఫీచర్ సాయంతో, మీ పరికరంలో రంగులు కనిపించే పద్ధతిని మీరు సర్దుబాటు చేయగలుగుతారు"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"కలర్ సరిచేయడం"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"\'కలర్ సరిచేయడం\' అనే ఫీచర్ సాయంతో, మీ పరికరంలో రంగులు కనిపించే పద్ధతిని మీరు మార్చగలుగుతారు"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
@@ -533,7 +533,7 @@
<string name="user_add_user_title" msgid="5457079143694924885">"కొత్త వినియోగదారుని జోడించాలా?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్లను సృష్టించడం ద్వారా మీరు ఈ దేవైజ్ను ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్కు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలీకరించవచ్చు. యూజర్లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్ ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగిలిన అందరు యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెస్ సామర్ధ్యం సెట్టింగ్లు మరియు సేవలు కొత్త యూజర్కి బదిలీ కాకపోవచ్చు."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"మీరు కొత్త వినియోగదారుని జోడించినప్పుడు, ఆ వ్యక్తి తన స్థలాన్ని సెటప్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగతా అందరు వినియోగదారుల కోసం యాప్లను అప్డేట్ చేయగలరు."</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"ఇప్పుడు వినియోగదారుని సెటప్ చేయాలా?"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"యూజర్ను ఇప్పుడే సెటప్ చేయాలా?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి నిల్వ స్థలాన్ని సెటప్ చేయండి"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ఇప్పుడు ప్రొఫైల్ను సెటప్ చేయాలా?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"ఇప్పుడే సెటప్ చేయి"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"అతిథిని జోడించండి"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"అతిథిని తీసివేయండి"</string>
<string name="guest_nickname" msgid="6332276931583337261">"అతిథి"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"పరికర ఆటోమేటిక్ సెట్టింగ్"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"డిజేబుల్ చేయబడింది"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ఎనేబుల్ చేయబడింది"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ఈ మార్పును వర్తింపజేయాలంటే మీరు మీ పరికరాన్ని తప్పనిసరిగా రీబూట్ చేయాలి. ఇప్పుడే రీబూట్ చేయండి లేదా రద్దు చేయండి."</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ఆఫీసు <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 0e958e9..a9032eb 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ปิดใช้"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"เปิดใช้"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"คุณต้องรีบูตอุปกรณ์เพื่อให้การเปลี่ยนแปลงนี้มีผล รีบูตเลยหรือยกเลิก"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> ในโปรไฟล์งาน"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 5ce89eb..712c06b 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Posibleng maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baka maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Naka-disable"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Na-enable"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Dapat i-reboot ang iyong device para mailapat ang pagbabagong ito. Mag-reboot ngayon o kanselahin."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> sa Trabaho"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 1e887d1..8818498 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Devre dışı"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Etkin"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu değişikliğin geçerli olması için cihazının yeniden başlatılması gerekir. Şimdi yeniden başlatın veya iptal edin."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (İş)"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index a95105b..f6568e3 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -226,12 +226,12 @@
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код підключення Wi‑Fi"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Помилка підключення"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Переконайтеся, що пристрій підключено до тієї ж мережі."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Підключати пристрій через Wi‑Fi за допомогою QR-коду"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Підключіть пристрій через Wi‑Fi за допомогою QR-коду"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Підключення пристрою…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Не вдалося підключитися до пристрою. Надано неправильний QR-код або пристрій не підключено до тієї ж мережі."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адреса та порт"</string>
- <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Сканувати QR-код"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Підключати пристрій через Wi‑Fi за допомогою QR-коду"</string>
+ <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Відскануйте QR-код"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Підключіть пристрій через Wi‑Fi за допомогою QR-коду"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Підключіть пристрій до мережі Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, налагодження, розробка"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Ярлик звіту про помилки"</string>
@@ -555,6 +555,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Вимкнено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Увімкнено"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Щоб застосувати ці зміни, перезапустіть пристрій. Перезапустіть пристрій або скасуйте зміни."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Робочий додаток <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index e056c1c..3776503 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -26,7 +26,7 @@
<item msgid="6050951078202663628">"مربوط ہو رہا ہے…"</item>
<item msgid="8356618438494652335">"توثیق ہو رہی ہے…"</item>
<item msgid="2837871868181677206">"IP پتہ حاصل کر رہا ہے…"</item>
- <item msgid="4613015005934755724">"مربوط ہو گیا"</item>
+ <item msgid="4613015005934755724">"منسلک"</item>
<item msgid="3763530049995655072">"معطل شدہ"</item>
<item msgid="7852381437933824454">"منقطع کیا جارہا ہے…"</item>
<item msgid="5046795712175415059">"منقطع ہو گیا"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 463c161..f13f8fb 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -433,7 +433,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> تک بیٹری چلے گی (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> تک بیٹری چلے گی"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> تک"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> تک بیٹری ختم ہو سکتی ہے"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> تک بیٹری ختم ہو سکتی ہے"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> سے زیادہ باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -549,14 +549,11 @@
<string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
<string name="guest_nickname" msgid="6332276931583337261">"مہمان"</string>
- <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) -->
- <skip />
- <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) -->
- <skip />
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"آلہ ڈیفالٹ"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غیر فعال"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"اس تبدیلی کو لاگو کرنے کے ليے آپ کے آلہ کو ریبوٹ کرنا ضروری ہے۔ ابھی ریبوٹ کریں یا منسوخ کریں۔"</string>
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"دفتر <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 762a246..7b8f627 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Yoqilmagan"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Yoniq"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Oʻzgarishlar qurilma oʻchib yonganda bajariladi. Hoziroq oʻchib yoqish yoki bekor qilish."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ish <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 12241f1..35cecc1 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Đã tắt"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Đã bật"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bạn phải khởi động lại thiết bị để áp dụng sự thay đổi này. Hãy khởi động lại ngay hoặc hủy."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> dành cho công việc"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 0a3ca12..c69ea2d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -419,7 +419,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"红色弱视(红绿不分)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"蓝色弱视(蓝黄不分)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"借助颜色校正功能,您可以调整设备上的颜色显示方式"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"借助色彩校正功能,您可以调整设备上的颜色显示方式"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已启用"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"设备必须重新启动才能应用此更改。您可以立即重新启动或取消。"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作资料中的<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 495cc22..b0324d9 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -222,7 +222,7 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"裝置指紋:<xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"連線失敗"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"請確認<xliff:g id="DEVICE_NAME">%1$s</xliff:g> 已連線至相同的網絡。"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"與裝置配對"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"配對裝置"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi-Fi 配對碼"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"配對失敗"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"請確認裝置已連線至相同的網絡。"</string>
@@ -452,7 +452,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充電"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"正在慢速充電"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"已插入電源插座,但目前無法充電"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"已連接電源插頭,但目前無法充電"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"電量已滿"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
<string name="disabled" msgid="8017887509554714950">"已停用"</string>
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"您的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作設定檔入面嘅「<xliff:g id="APP_NAME">%s</xliff:g>」"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 9445268..0574c7e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"裝置必須重新啟動才能套用這項變更。請立即重新啟動或取消變更。"</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作資料夾中的<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 86698f4..b60553a 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -553,6 +553,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ikhutshaziwe"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Inikwe amandla"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kufanele idivayisi yakho iqaliswe ukuze lolu shintsho lusebenze. Qalisa manje noma khansela."</string>
- <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) -->
+ <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Umsebenzi we-<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 9e8c70f..197e34d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -145,15 +145,16 @@
/**
* Connect the MediaDevice to transfer media
* @param connectDevice the MediaDevice
+ * @return {@code true} if successfully call, otherwise return {@code false}
*/
- public void connectDevice(MediaDevice connectDevice) {
+ public boolean connectDevice(MediaDevice connectDevice) {
MediaDevice device = null;
synchronized (mMediaDevicesLock) {
device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
}
if (device == null) {
Log.w(TAG, "connectDevice() connectDevice not in the list!");
- return;
+ return false;
}
if (device instanceof BluetoothMediaDevice) {
final CachedBluetoothDevice cachedDevice =
@@ -162,13 +163,13 @@
mOnTransferBluetoothDevice = connectDevice;
device.setState(MediaDeviceState.STATE_CONNECTING);
cachedDevice.connect();
- return;
+ return true;
}
}
if (device == mCurrentConnectedDevice) {
Log.d(TAG, "connectDevice() this device all ready connected! : " + device.getName());
- return;
+ return false;
}
if (mCurrentConnectedDevice != null) {
@@ -181,6 +182,7 @@
} else {
device.connect();
}
+ return true;
}
void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
index 365a16c..517071b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -141,7 +141,7 @@
when(currentDevice.getId()).thenReturn(TEST_CURRENT_DEVICE_ID);
mLocalMediaManager.registerCallback(mCallback);
- mLocalMediaManager.connectDevice(device);
+ assertThat(mLocalMediaManager.connectDevice(device)).isTrue();
verify(currentDevice).disconnect();
verify(device).connect();
@@ -154,7 +154,7 @@
mLocalMediaManager.mCurrentConnectedDevice = mInfoMediaDevice1;
mLocalMediaManager.registerCallback(mCallback);
- mLocalMediaManager.connectDevice(mInfoMediaDevice2);
+ assertThat(mLocalMediaManager.connectDevice(mInfoMediaDevice2)).isTrue();
assertThat(mInfoMediaDevice2.getState()).isEqualTo(LocalMediaManager.MediaDeviceState
.STATE_CONNECTING);
@@ -167,7 +167,7 @@
mLocalMediaManager.mCurrentConnectedDevice = mInfoMediaDevice1;
mLocalMediaManager.registerCallback(mCallback);
- mLocalMediaManager.connectDevice(mInfoMediaDevice1);
+ assertThat(mLocalMediaManager.connectDevice(mInfoMediaDevice1)).isFalse();
assertThat(mInfoMediaDevice1.getState()).isNotEqualTo(LocalMediaManager.MediaDeviceState
.STATE_CONNECTING);
@@ -185,7 +185,7 @@
when(cachedDevice.isBusy()).thenReturn(false);
mLocalMediaManager.registerCallback(mCallback);
- mLocalMediaManager.connectDevice(device);
+ assertThat(mLocalMediaManager.connectDevice(device)).isTrue();
verify(cachedDevice).connect();
}
diff --git a/packages/SystemUI/res/drawable/stat_sys_media.xml b/packages/SystemUI/res/drawable/stat_sys_media.xml
new file mode 100644
index 0000000..d48db7b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_media.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="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M5,7.81l0,8.38l6,-4.19z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M13,8h2v8h-2z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M17,8h2v8h-2z"
+ android:fillColor="#000000"/>
+</vector>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8bbcfa0..de48317 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -790,6 +790,9 @@
<!-- Accessibility text describing sensors off active. [CHAR LIMIT=NONE] -->
<string name="accessibility_sensors_off_active">Sensors off active</string>
+ <!-- Accessibility text describing that media is playing. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_media_active">Media is active</string>
+
<!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_clear_all">Clear all notifications.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index d008088..f1cb667 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -28,7 +28,7 @@
import com.android.internal.os.BinderInternal;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dump.DumpManager;
+import com.android.systemui.dump.DumpHandler;
import com.android.systemui.dump.SystemUIAuxiliaryDumpService;
import java.io.FileDescriptor;
@@ -39,15 +39,15 @@
public class SystemUIService extends Service {
private final Handler mMainHandler;
- private final DumpManager mDumpManager;
+ private final DumpHandler mDumpHandler;
@Inject
public SystemUIService(
@Main Handler mainHandler,
- DumpManager dumpManager) {
+ DumpHandler dumpHandler) {
super();
mMainHandler = mainHandler;
- mDumpManager = dumpManager;
+ mDumpHandler = dumpHandler;
}
@Override
@@ -94,10 +94,10 @@
String[] massagedArgs = args;
if (args.length == 0) {
massagedArgs = new String[] {
- DumpManager.PRIORITY_ARG,
- DumpManager.PRIORITY_ARG_CRITICAL};
+ DumpHandler.PRIORITY_ARG,
+ DumpHandler.PRIORITY_ARG_CRITICAL};
}
- mDumpManager.dump(fd, pw, massagedArgs);
+ mDumpHandler.dump(fd, pw, massagedArgs);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index a1f4c96..181170b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -89,35 +89,36 @@
contentResolver, CONTROLS_AVAILABLE, DEFAULT_ENABLED, currentUserId) != 0
private set
- private var file = Environment.buildPath(
- context.filesDir,
- ControlsFavoritePersistenceWrapper.FILE_NAME
- )
- private var auxiliaryFile = Environment.buildPath(
- context.filesDir,
- AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME
- )
- private val persistenceWrapper = optionalWrapper.orElseGet {
- ControlsFavoritePersistenceWrapper(
- file,
- executor,
- BackupManager(context)
+ private val persistenceWrapper: ControlsFavoritePersistenceWrapper
+ @VisibleForTesting
+ internal var auxiliaryPersistenceWrapper: AuxiliaryPersistenceWrapper
+
+ init {
+ val userStructure = UserStructure(context, currentUser)
+
+ persistenceWrapper = optionalWrapper.orElseGet {
+ ControlsFavoritePersistenceWrapper(
+ userStructure.file,
+ executor,
+ BackupManager(userStructure.userContext)
+ )
+ }
+
+ auxiliaryPersistenceWrapper = AuxiliaryPersistenceWrapper(
+ userStructure.auxiliaryFile,
+ executor
)
}
- @VisibleForTesting
- internal var auxiliaryPersistenceWrapper = AuxiliaryPersistenceWrapper(auxiliaryFile, executor)
-
private fun setValuesForUser(newUser: UserHandle) {
Log.d(TAG, "Changing to user: $newUser")
currentUser = newUser
- val userContext = context.createContextAsUser(currentUser, 0)
- file = Environment.buildPath(
- userContext.filesDir, ControlsFavoritePersistenceWrapper.FILE_NAME)
- auxiliaryFile = Environment.buildPath(
- userContext.filesDir, AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME)
- persistenceWrapper.changeFileAndBackupManager(file, BackupManager(userContext))
- auxiliaryPersistenceWrapper.changeFile(auxiliaryFile)
+ val userStructure = UserStructure(context, currentUser)
+ persistenceWrapper.changeFileAndBackupManager(
+ userStructure.file,
+ BackupManager(userStructure.userContext)
+ )
+ auxiliaryPersistenceWrapper.changeFile(userStructure.auxiliaryFile)
available = Settings.Secure.getIntForUser(contentResolver, CONTROLS_AVAILABLE,
DEFAULT_ENABLED, newUser.identifier) != 0
resetFavorites(available)
@@ -564,6 +565,20 @@
}
}
+class UserStructure(context: Context, user: UserHandle) {
+ val userContext = context.createContextAsUser(user, 0)
+
+ val file = Environment.buildPath(
+ context.filesDir,
+ ControlsFavoritePersistenceWrapper.FILE_NAME
+ )
+
+ val auxiliaryFile = Environment.buildPath(
+ context.filesDir,
+ AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME
+ )
+}
+
/**
* Relies on immutable data for thread safety. When necessary to update favMap, use reassignment to
* replace it, which will not disrupt any ongoing map traversal.
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
new file mode 100644
index 0000000..fa951fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
@@ -0,0 +1,311 @@
+/*
+ * 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.dump
+
+import android.content.Context
+import android.os.SystemClock
+import android.os.Trace
+import com.android.systemui.R
+import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_CRITICAL
+import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_HIGH
+import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_NORMAL
+import com.android.systemui.log.LogBuffer
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/**
+ * Oversees SystemUI's output during bug reports (and dumpsys in general)
+ *
+ * Dump output is split into two sections, CRITICAL and NORMAL. In general, the CRITICAL section
+ * contains all dumpables that were registered to the [DumpManager], while the NORMAL sections
+ * contains all [LogBuffer]s (due to their length).
+ *
+ * The CRITICAL and NORMAL sections can be found within a bug report by searching for
+ * "SERVICE com.android.systemui/.SystemUIService" and
+ * "SERVICE com.android.systemui/.dump.SystemUIAuxiliaryDumpService", respectively.
+ *
+ * Finally, some or all of the dump can be triggered on-demand via adb (see below).
+ *
+ * ```
+ * # For the following, let <invocation> be:
+ * $ adb shell dumpsys activity service com.android.systemui/.SystemUIService
+ *
+ * # To dump specific target(s), specify one or more registered names:
+ * $ <invocation> NotifCollection
+ * $ <invocation> StatusBar FalsingManager BootCompleteCacheImpl
+ *
+ * # Log buffers can be dumped in the same way (and can even be mixed in with other dump targets,
+ * # although it's not clear why one would want such a thing):
+ * $ <invocation> NotifLog
+ * $ <invocation> StatusBar NotifLog BootCompleteCacheImpl
+ *
+ * # If passing -t or --tail, shows only the last N lines of any log buffers:
+ * $ <invocation> NotifLog --tail 100
+ *
+ * # Dump targets are matched using String.endsWith(), so dumpables that register using their
+ * # fully-qualified class name can still be dumped using their short name:
+ * $ <invocation> com.android.keyguard.KeyguardUpdateMonitor
+ * $ <invocation> keyguard.KeyguardUpdateMonitor
+ * $ <invocation> KeyguardUpdateMonitor
+ *
+ * # To dump all dumpables or all buffers:
+ * $ <invocation> dumpables
+ * $ <invocation> buffers
+ *
+ * # Finally, the following will simulate what we dump during the CRITICAL and NORMAL sections of a
+ * # bug report:
+ * $ <invocation> bugreport-critical
+ * $ <invocation> bugreport-normal
+ *
+ * # And if you need to be reminded of this list of commands:
+ * $ <invocation> -h
+ * $ <invocation> --help
+ * ```
+ */
+class DumpHandler @Inject constructor(
+ private val context: Context,
+ private val dumpManager: DumpManager,
+ private val logBufferEulogizer: LogBufferEulogizer
+) {
+ /**
+ * Dump the diagnostics! Behavior can be controlled via [args].
+ */
+ fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+ Trace.beginSection("DumpManager#dump()")
+ val start = SystemClock.uptimeMillis()
+
+ val parsedArgs = try {
+ parseArgs(args)
+ } catch (e: ArgParseException) {
+ pw.println(e.message)
+ return
+ }
+
+ when (parsedArgs.dumpPriority) {
+ PRIORITY_ARG_CRITICAL -> dumpCritical(fd, pw, parsedArgs)
+ PRIORITY_ARG_NORMAL -> dumpNormal(pw, parsedArgs)
+ else -> dumpParameterized(fd, pw, parsedArgs)
+ }
+
+ pw.println()
+ pw.println("Dump took ${SystemClock.uptimeMillis() - start}ms")
+ Trace.endSection()
+ }
+
+ private fun dumpParameterized(fd: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
+ when (args.command) {
+ "bugreport-critical" -> dumpCritical(fd, pw, args)
+ "bugreport-normal" -> dumpNormal(pw, args)
+ "dumpables" -> dumpDumpables(fd, pw, args)
+ "buffers" -> dumpBuffers(pw, args)
+ "config" -> dumpConfig(pw)
+ "help" -> dumpHelp(pw)
+ else -> dumpTargets(args.nonFlagArgs, fd, pw, args)
+ }
+ }
+
+ private fun dumpCritical(fd: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
+ dumpManager.dumpDumpables(fd, pw, args.rawArgs)
+ dumpConfig(pw)
+ }
+
+ private fun dumpNormal(pw: PrintWriter, args: ParsedArgs) {
+ dumpManager.dumpBuffers(pw, args.tailLength)
+ logBufferEulogizer.readEulogyIfPresent(pw)
+ }
+
+ private fun dumpDumpables(fw: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
+ if (args.listOnly) {
+ dumpManager.listDumpables(pw)
+ } else {
+ dumpManager.dumpDumpables(fw, pw, args.rawArgs)
+ }
+ }
+
+ private fun dumpBuffers(pw: PrintWriter, args: ParsedArgs) {
+ if (args.listOnly) {
+ dumpManager.listBuffers(pw)
+ } else {
+ dumpManager.dumpBuffers(pw, args.tailLength)
+ }
+ }
+
+ private fun dumpTargets(
+ targets: List<String>,
+ fd: FileDescriptor,
+ pw: PrintWriter,
+ args: ParsedArgs
+ ) {
+ if (targets.isNotEmpty()) {
+ for (target in targets) {
+ dumpManager.dumpTarget(target, fd, pw, args.rawArgs, args.tailLength)
+ }
+ } else {
+ if (args.listOnly) {
+ pw.println("Dumpables:")
+ dumpManager.listDumpables(pw)
+ pw.println()
+
+ pw.println("Buffers:")
+ dumpManager.listBuffers(pw)
+ } else {
+ pw.println("Nothing to dump :(")
+ }
+ }
+ }
+
+ private fun dumpConfig(pw: PrintWriter) {
+ pw.println("SystemUiServiceComponents configuration:")
+ pw.print("vendor component: ")
+ pw.println(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
+ dumpServiceList(pw, "global", R.array.config_systemUIServiceComponents)
+ dumpServiceList(pw, "per-user", R.array.config_systemUIServiceComponentsPerUser)
+ }
+
+ private fun dumpServiceList(pw: PrintWriter, type: String, resId: Int) {
+ val services: Array<String>? = context.resources.getStringArray(resId)
+ pw.print(type)
+ pw.print(": ")
+ if (services == null) {
+ pw.println("N/A")
+ return
+ }
+ pw.print(services.size)
+ pw.println(" services")
+ for (i in services.indices) {
+ pw.print(" ")
+ pw.print(i)
+ pw.print(": ")
+ pw.println(services[i])
+ }
+ }
+
+ private fun dumpHelp(pw: PrintWriter) {
+ pw.println("Let <invocation> be:")
+ pw.println("$ adb shell dumpsys activity service com.android.systemui/.SystemUIService")
+ pw.println()
+
+ pw.println("Most common usage:")
+ pw.println("$ <invocation> <targets>")
+ pw.println("$ <invocation> NotifLog")
+ pw.println("$ <invocation> StatusBar FalsingManager BootCompleteCacheImpl")
+ pw.println("etc.")
+ pw.println()
+
+ pw.println("Special commands:")
+ pw.println("$ <invocation> dumpables")
+ pw.println("$ <invocation> buffers")
+ pw.println("$ <invocation> bugreport-critical")
+ pw.println("$ <invocation> bugreport-normal")
+ pw.println()
+
+ pw.println("Targets can be listed:")
+ pw.println("$ <invocation> --list")
+ pw.println("$ <invocation> dumpables --list")
+ pw.println("$ <invocation> buffers --list")
+ pw.println()
+
+ pw.println("Show only the most recent N lines of buffers")
+ pw.println("$ <invocation> NotifLog --tail 30")
+ }
+
+ private fun parseArgs(args: Array<String>): ParsedArgs {
+ val mutArgs = args.toMutableList()
+ val pArgs = ParsedArgs(args, mutArgs)
+
+ val iterator = mutArgs.iterator()
+ while (iterator.hasNext()) {
+ val arg = iterator.next()
+ if (arg.startsWith("-")) {
+ iterator.remove()
+ when (arg) {
+ PRIORITY_ARG -> {
+ pArgs.dumpPriority = readArgument(iterator, PRIORITY_ARG) {
+ if (PRIORITY_OPTIONS.contains(it)) {
+ it
+ } else {
+ throw IllegalArgumentException()
+ }
+ }
+ }
+ "-t", "--tail" -> {
+ pArgs.tailLength = readArgument(iterator, arg) {
+ it.toInt()
+ }
+ }
+ "-l", "--list" -> {
+ pArgs.listOnly = true
+ }
+ "-h", "--help" -> {
+ pArgs.command = "help"
+ }
+ else -> {
+ throw ArgParseException("Unknown flag: $arg")
+ }
+ }
+ }
+ }
+
+ if (pArgs.command == null && mutArgs.isNotEmpty() && COMMANDS.contains(mutArgs[0])) {
+ pArgs.command = mutArgs.removeAt(0)
+ }
+
+ return pArgs
+ }
+
+ private fun <T> readArgument(
+ iterator: MutableIterator<String>,
+ flag: String,
+ parser: (arg: String) -> T
+ ): T {
+ if (!iterator.hasNext()) {
+ throw ArgParseException("Missing argument for $flag")
+ }
+ val value = iterator.next()
+
+ return try {
+ parser(value).also { iterator.remove() }
+ } catch (e: Exception) {
+ throw ArgParseException("Invalid argument '$value' for flag $flag")
+ }
+ }
+
+ companion object {
+ const val PRIORITY_ARG = "--dump-priority"
+ const val PRIORITY_ARG_CRITICAL = "CRITICAL"
+ const val PRIORITY_ARG_HIGH = "HIGH"
+ const val PRIORITY_ARG_NORMAL = "NORMAL"
+ }
+}
+
+private val PRIORITY_OPTIONS =
+ arrayOf(PRIORITY_ARG_CRITICAL, PRIORITY_ARG_HIGH, PRIORITY_ARG_NORMAL)
+
+private val COMMANDS = arrayOf("bugreport-critical", "bugreport-normal", "buffers", "dumpables")
+
+private class ParsedArgs(
+ val rawArgs: Array<String>,
+ val nonFlagArgs: List<String>
+) {
+ var dumpPriority: String? = null
+ var tailLength: Int = 0
+ var command: String? = null
+ var listOnly = false
+}
+
+class ArgParseException(message: String) : Exception(message)
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
index 59a7a32..a4141b1 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
@@ -16,15 +16,8 @@
package com.android.systemui.dump
-import android.content.Context
-import android.os.SystemClock
-import android.os.Trace
import android.util.ArrayMap
import com.android.systemui.Dumpable
-import com.android.systemui.R
-import com.android.systemui.dump.DumpManager.Companion.PRIORITY_ARG_CRITICAL
-import com.android.systemui.dump.DumpManager.Companion.PRIORITY_ARG_HIGH
-import com.android.systemui.dump.DumpManager.Companion.PRIORITY_ARG_NORMAL
import com.android.systemui.log.LogBuffer
import java.io.FileDescriptor
import java.io.PrintWriter
@@ -32,58 +25,16 @@
import javax.inject.Singleton
/**
- * Oversees SystemUI's output during bug reports (and dumpsys in general)
+ * Maintains a registry of things that should be dumped when a bug report is taken
*
* When a bug report is taken, SystemUI dumps various diagnostic information that we hope will be
* useful for the eventual readers of the bug report. Code that wishes to participate in this dump
* should register itself here.
*
- * Dump output is split into two sections, CRITICAL and NORMAL. All dumpables registered via
- * [registerDumpable] appear in the CRITICAL section, while all [LogBuffer]s appear in the NORMAL
- * section (due to their length).
- *
- * The CRITICAL and NORMAL sections can be found within a bug report by searching for
- * "SERVICE com.android.systemui/.SystemUIService" and
- * "SERVICE com.android.systemui/.dump.SystemUIAuxiliaryDumpService", respectively.
- *
- * Finally, some or all of the dump can be triggered on-demand via adb (see below).
- *
- * ```
- * # For the following, let <invocation> be:
- * $ adb shell dumpsys activity service com.android.systemui/.SystemUIService
- *
- * # To dump specific target(s), specify one or more registered names:
- * $ <invocation> NotifCollection
- * $ <invocation> StatusBar FalsingManager BootCompleteCacheImpl
- *
- * # Log buffers can be dumped in the same way (and can even be mixed in with other dump targets,
- * # although it's not clear why one would want such a thing):
- * $ <invocation> NotifLog
- * $ <invocation> StatusBar NotifLog BootCompleteCacheImpl
- *
- * # If passing -t or --tail, shows only the last N lines of any log buffers:
- * $ <invocation> NotifLog --tail 100
- *
- * # Dump targets are matched using String.endsWith(), so dumpables that register using their
- * # fully-qualified class name can still be dumped using their short name:
- * $ <invocation> com.android.keyguard.KeyguardUpdateMonitor
- * $ <invocation> keyguard.KeyguardUpdateMonitor
- * $ <invocation> KeyguardUpdateMonitor
- *
- * # To dump all dumpables or all buffers:
- * $ <invocation> dumpables
- * $ <invocation> buffers
- *
- * Finally, the following will simulate what we dump during the CRITICAL and NORMAL sections of a
- * bug report:
- * $ <invocation> bugreport-critical
- * $ <invocation> bugreport-normal
- * ```
+ * See [DumpHandler] for more information on how and when this information is dumped.
*/
@Singleton
-class DumpManager @Inject constructor(
- private val context: Context
-) {
+class DumpManager @Inject constructor() {
private val dumpables: MutableMap<String, RegisteredDumpable<Dumpable>> = ArrayMap()
private val buffers: MutableMap<String, RegisteredDumpable<LogBuffer>> = ArrayMap()
@@ -97,10 +48,6 @@
*/
@Synchronized
fun registerDumpable(name: String, module: Dumpable) {
- if (RESERVED_NAMES.contains(name)) {
- throw IllegalArgumentException("'$name' is reserved")
- }
-
if (!canAssignToNameLocked(name, module)) {
throw IllegalArgumentException("'$name' is already registered")
}
@@ -128,76 +75,16 @@
}
/**
- * Dump the diagnostics! Behavior can be controlled via [args].
+ * Dumps the first dumpable or buffer whose registered name ends with [target]
*/
@Synchronized
- fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
- Trace.beginSection("DumpManager#dump()")
- val start = SystemClock.uptimeMillis()
-
- val parsedArgs = try {
- parseArgs(args)
- } catch (e: ArgParseException) {
- pw.println(e.message)
- return
- }
-
- when (parsedArgs.dumpPriority) {
- PRIORITY_ARG_CRITICAL -> dumpCriticalLocked(fd, pw, parsedArgs)
- PRIORITY_ARG_NORMAL -> dumpNormalLocked(pw, parsedArgs)
- else -> dumpParameterizedLocked(fd, pw, parsedArgs)
- }
-
- pw.println()
- pw.println("Dump took ${SystemClock.uptimeMillis() - start}ms")
- Trace.endSection()
- }
-
- private fun dumpCriticalLocked(fd: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
- dumpDumpablesLocked(fd, pw, args)
- dumpConfig(pw)
- }
-
- private fun dumpNormalLocked(pw: PrintWriter, args: ParsedArgs) {
- dumpBuffersLocked(pw, args)
- }
-
- private fun dumpParameterizedLocked(fd: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
- when (args.command) {
- "bugreport-critical" -> dumpCriticalLocked(fd, pw, args)
- "bugreport-normal" -> dumpNormalLocked(pw, args)
- "dumpables" -> dumpDumpablesLocked(fd, pw, args)
- "buffers" -> dumpBuffersLocked(pw, args)
- else -> dumpTargetsLocked(args.nonFlagArgs, fd, pw, args)
- }
- }
-
- private fun dumpTargetsLocked(
- targets: List<String>,
- fd: FileDescriptor,
- pw: PrintWriter,
- args: ParsedArgs
- ) {
- if (targets.isEmpty()) {
- pw.println("Nothing to dump :(")
- } else {
- for (target in targets) {
- dumpTarget(target, fd, pw, args)
- }
- }
- }
-
- private fun dumpTarget(
+ fun dumpTarget(
target: String,
fd: FileDescriptor,
pw: PrintWriter,
- args: ParsedArgs
+ args: Array<String>,
+ tailLength: Int
) {
- if (target == "config") {
- dumpConfig(pw)
- return
- }
-
for (dumpable in dumpables.values) {
if (dumpable.name.endsWith(target)) {
dumpDumpable(dumpable, fd, pw, args)
@@ -207,21 +94,49 @@
for (buffer in buffers.values) {
if (buffer.name.endsWith(target)) {
- dumpBuffer(buffer, pw, args)
+ dumpBuffer(buffer, pw, tailLength)
return
}
}
}
- private fun dumpDumpablesLocked(fd: FileDescriptor, pw: PrintWriter, args: ParsedArgs) {
+ /**
+ * Dumps all registered dumpables to [pw]
+ */
+ @Synchronized
+ fun dumpDumpables(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
for (module in dumpables.values) {
dumpDumpable(module, fd, pw, args)
}
}
- private fun dumpBuffersLocked(pw: PrintWriter, args: ParsedArgs) {
+ /**
+ * Dumps the names of all registered dumpables (one per line)
+ */
+ @Synchronized
+ fun listDumpables(pw: PrintWriter) {
+ for (module in dumpables.values) {
+ pw.println(module.name)
+ }
+ }
+
+ /**
+ * Dumps all registered [LogBuffer]s to [pw]
+ */
+ @Synchronized
+ fun dumpBuffers(pw: PrintWriter, tailLength: Int) {
for (buffer in buffers.values) {
- dumpBuffer(buffer, pw, args)
+ dumpBuffer(buffer, pw, tailLength)
+ }
+ }
+
+ /**
+ * Dumps the names of all registered buffers (one per line)
+ */
+ @Synchronized
+ fun listBuffers(pw: PrintWriter) {
+ for (buffer in buffers.values) {
+ pw.println(buffer.name)
}
}
@@ -229,139 +144,33 @@
dumpable: RegisteredDumpable<Dumpable>,
fd: FileDescriptor,
pw: PrintWriter,
- args: ParsedArgs
+ args: Array<String>
) {
pw.println()
pw.println("${dumpable.name}:")
pw.println("----------------------------------------------------------------------------")
- dumpable.dumpable.dump(fd, pw, args.rawArgs)
+ dumpable.dumpable.dump(fd, pw, args)
}
private fun dumpBuffer(
buffer: RegisteredDumpable<LogBuffer>,
pw: PrintWriter,
- args: ParsedArgs
+ tailLength: Int
) {
pw.println()
pw.println()
pw.println("BUFFER ${buffer.name}:")
pw.println("============================================================================")
- buffer.dumpable.dump(pw, args.tailLength)
- }
-
- private fun dumpConfig(pw: PrintWriter) {
- pw.println("SystemUiServiceComponents configuration:")
- pw.print("vendor component: ")
- pw.println(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
- dumpServiceList(pw, "global", R.array.config_systemUIServiceComponents)
- dumpServiceList(pw, "per-user", R.array.config_systemUIServiceComponentsPerUser)
- }
-
- private fun dumpServiceList(pw: PrintWriter, type: String, resId: Int) {
- val services: Array<String>? = context.resources.getStringArray(resId)
- pw.print(type)
- pw.print(": ")
- if (services == null) {
- pw.println("N/A")
- return
- }
- pw.print(services.size)
- pw.println(" services")
- for (i in services.indices) {
- pw.print(" ")
- pw.print(i)
- pw.print(": ")
- pw.println(services[i])
- }
- }
-
- private fun parseArgs(args: Array<String>): ParsedArgs {
- val mutArgs = args.toMutableList()
- val pArgs = ParsedArgs(args, mutArgs)
-
- val iterator = mutArgs.iterator()
- while (iterator.hasNext()) {
- val arg = iterator.next()
- if (arg.startsWith("-")) {
- iterator.remove()
- when (arg) {
- PRIORITY_ARG -> {
- pArgs.dumpPriority = readArgument(iterator, PRIORITY_ARG) {
- if (PRIORITY_OPTIONS.contains(it)) {
- it
- } else {
- throw IllegalArgumentException()
- }
- }
- }
- "-t", "--tail" -> {
- pArgs.tailLength = readArgument(iterator, "--tail") {
- it.toInt()
- }
- }
- else -> {
- throw ArgParseException("Unknown flag: $arg")
- }
- }
- }
- }
-
- if (mutArgs.isNotEmpty() && COMMANDS.contains(mutArgs[0])) {
- pArgs.command = mutArgs.removeAt(0)
- }
-
- return pArgs
- }
-
- private fun <T> readArgument(
- iterator: MutableIterator<String>,
- flag: String,
- parser: (arg: String) -> T
- ): T {
- if (!iterator.hasNext()) {
- throw ArgParseException("Missing argument for $flag")
- }
- val value = iterator.next()
-
- return try {
- parser(value).also { iterator.remove() }
- } catch (e: Exception) {
- throw ArgParseException("Invalid argument '$value' for flag $flag")
- }
+ buffer.dumpable.dump(pw, tailLength)
}
private fun canAssignToNameLocked(name: String, newDumpable: Any): Boolean {
val existingDumpable = dumpables[name]?.dumpable ?: buffers[name]?.dumpable
return existingDumpable == null || newDumpable == existingDumpable
}
-
- companion object {
- const val PRIORITY_ARG = "--dump-priority"
- const val PRIORITY_ARG_CRITICAL = "CRITICAL"
- const val PRIORITY_ARG_HIGH = "HIGH"
- const val PRIORITY_ARG_NORMAL = "NORMAL"
- }
}
-private val PRIORITY_OPTIONS =
- arrayOf(PRIORITY_ARG_CRITICAL, PRIORITY_ARG_HIGH, PRIORITY_ARG_NORMAL)
-
-private val COMMANDS = arrayOf("bugreport-critical", "bugreport-normal", "buffers", "dumpables")
-
-private val RESERVED_NAMES = arrayOf("config", *COMMANDS)
-
private data class RegisteredDumpable<T>(
val name: String,
val dumpable: T
)
-
-private class ParsedArgs(
- val rawArgs: Array<String>,
- val nonFlagArgs: List<String>
-) {
- var dumpPriority: String? = null
- var tailLength: Int = 0
- var command: String? = null
-}
-
-class ArgParseException(message: String) : Exception(message)
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt b/packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
new file mode 100644
index 0000000..603cb67
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
@@ -0,0 +1,150 @@
+/*
+ * 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.dump
+
+import android.content.Context
+import android.util.Log
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.util.io.Files
+import com.android.systemui.util.time.SystemClock
+import java.io.IOException
+import java.io.PrintWriter
+import java.io.UncheckedIOException
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.nio.file.StandardOpenOption.CREATE
+import java.nio.file.StandardOpenOption.TRUNCATE_EXISTING
+import java.nio.file.attribute.BasicFileAttributes
+import java.text.SimpleDateFormat
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Dumps all [LogBuffer]s to a file
+ *
+ * Intended for emergencies, i.e. we're about to crash. This file can then be read at a later date
+ * (usually in a bug report).
+ */
+@Singleton
+class LogBufferEulogizer(
+ private val dumpManager: DumpManager,
+ private val systemClock: SystemClock,
+ private val files: Files,
+ private val logPath: Path,
+ private val minWriteGap: Long,
+ private val maxLogAgeToDump: Long
+) {
+ @Inject constructor(
+ context: Context,
+ dumpManager: DumpManager,
+ systemClock: SystemClock,
+ files: Files
+ ) : this(
+ dumpManager,
+ systemClock,
+ files,
+ Paths.get(context.filesDir.toPath().toString(), "log_buffers.txt"),
+ MIN_WRITE_GAP,
+ MAX_AGE_TO_DUMP
+ )
+
+ /**
+ * Dumps all active log buffers to a file
+ *
+ * The file will be prefaced by the [reason], which will then be returned (presumably so it can
+ * be thrown).
+ */
+ fun <T : Exception> record(reason: T): T {
+ val start = systemClock.uptimeMillis()
+ var duration = 0L
+
+ Log.i(TAG, "Performing emergency dump of log buffers")
+
+ val millisSinceLastWrite = getMillisSinceLastWrite(logPath)
+ if (millisSinceLastWrite < minWriteGap) {
+ Log.w(TAG, "Cannot dump logs, last write was only $millisSinceLastWrite ms ago")
+ return reason
+ }
+
+ try {
+ val writer = files.newBufferedWriter(logPath, CREATE, TRUNCATE_EXISTING)
+ writer.use { out ->
+ val pw = PrintWriter(out)
+
+ pw.println(DATE_FORMAT.format(systemClock.currentTimeMillis()))
+ pw.println()
+ pw.println("Dump triggered by exception:")
+ reason.printStackTrace(pw)
+ dumpManager.dumpBuffers(pw, 0)
+ duration = systemClock.uptimeMillis() - start
+ pw.println()
+ pw.println("Buffer eulogy took ${duration}ms")
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Exception while attempting to dump buffers, bailing", e)
+ }
+
+ Log.i(TAG, "Buffer eulogy took ${duration}ms")
+
+ return reason
+ }
+
+ /**
+ * If a eulogy file is present, writes its contents to [pw].
+ */
+ fun readEulogyIfPresent(pw: PrintWriter) {
+ try {
+ val millisSinceLastWrite = getMillisSinceLastWrite(logPath)
+ if (millisSinceLastWrite > maxLogAgeToDump) {
+ Log.i(TAG, "Not eulogizing buffers; they are " +
+ TimeUnit.HOURS.convert(millisSinceLastWrite, TimeUnit.MILLISECONDS) +
+ " hours old")
+ return
+ }
+
+ files.lines(logPath).use { s ->
+ pw.println()
+ pw.println()
+ pw.println("=============== BUFFERS FROM MOST RECENT CRASH ===============")
+ s.forEach { line ->
+ pw.println(line)
+ }
+ }
+ } catch (e: IOException) {
+ // File doesn't exist, okay
+ } catch (e: UncheckedIOException) {
+ Log.e(TAG, "UncheckedIOException while dumping the core", e)
+ }
+ }
+
+ private fun getMillisSinceLastWrite(path: Path): Long {
+ val stats = try {
+ files.readAttributes(path, BasicFileAttributes::class.java)
+ } catch (e: IOException) {
+ // File doesn't exist
+ null
+ }
+ return systemClock.currentTimeMillis() - (stats?.lastModifiedTime()?.toMillis() ?: 0)
+ }
+}
+
+private const val TAG = "BufferEulogizer"
+private val MIN_WRITE_GAP = TimeUnit.MINUTES.toMillis(5)
+private val MAX_AGE_TO_DUMP = TimeUnit.HOURS.toMillis(48)
+private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dump/SystemUIAuxiliaryDumpService.java b/packages/SystemUI/src/com/android/systemui/dump/SystemUIAuxiliaryDumpService.java
index 431cd63..da983ab 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/SystemUIAuxiliaryDumpService.java
+++ b/packages/SystemUI/src/com/android/systemui/dump/SystemUIAuxiliaryDumpService.java
@@ -35,11 +35,11 @@
* all other services.
*/
public class SystemUIAuxiliaryDumpService extends Service {
- private final DumpManager mDumpManager;
+ private final DumpHandler mDumpHandler;
@Inject
- public SystemUIAuxiliaryDumpService(DumpManager dumpManager) {
- mDumpManager = dumpManager;
+ public SystemUIAuxiliaryDumpService(DumpHandler dumpHandler) {
+ mDumpHandler = dumpHandler;
}
@Override
@@ -50,9 +50,9 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
// Simulate the NORMAL priority arg being passed to us
- mDumpManager.dump(
+ mDumpHandler.dump(
fd,
pw,
- new String[] { DumpManager.PRIORITY_ARG, DumpManager.PRIORITY_ARG_NORMAL });
+ new String[] { DumpHandler.PRIORITY_ARG, DumpHandler.PRIORITY_ARG_NORMAL });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index 7defef9..342db34 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -209,4 +209,4 @@
}
private const val TAG = "LogBuffer"
-private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.S", Locale.US)
+private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
diff --git a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
index 4ee4ad4..85e1c6b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
@@ -18,6 +18,7 @@
import android.view.View
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.MediaHeaderView
@@ -33,7 +34,8 @@
class KeyguardMediaController @Inject constructor(
private val mediaHost: MediaHost,
private val bypassController: KeyguardBypassController,
- private val statusBarStateController: SysuiStatusBarStateController
+ private val statusBarStateController: SysuiStatusBarStateController,
+ private val notifLockscreenUserManager: NotificationLockscreenUserManager
) {
init {
@@ -61,10 +63,12 @@
}
private fun updateVisibility() {
- val shouldBeVisible = mediaHost.visible
- && !bypassController.bypassEnabled
- && (statusBarStateController.state == StatusBarState.KEYGUARD ||
- statusBarStateController.state == StatusBarState.FULLSCREEN_USER_SWITCHER)
+ val keyguardOrUserSwitcher = (statusBarStateController.state == StatusBarState.KEYGUARD ||
+ statusBarStateController.state == StatusBarState.FULLSCREEN_USER_SWITCHER)
+ val shouldBeVisible = mediaHost.visible &&
+ !bypassController.bypassEnabled &&
+ keyguardOrUserSwitcher &&
+ notifLockscreenUserManager.shouldShowLockscreenNotifications()
view?.visibility = if (shouldBeVisible) View.VISIBLE else View.GONE
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt
new file mode 100644
index 0000000..94a0835
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.media
+
+import android.content.Context
+
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.settingslib.media.InfoMediaManager
+import com.android.settingslib.media.LocalMediaManager
+
+import javax.inject.Inject
+
+/**
+ * Factory to create [LocalMediaManager] objects.
+ */
+class LocalMediaManagerFactory @Inject constructor(
+ private val context: Context,
+ private val localBluetoothManager: LocalBluetoothManager?
+) {
+ /** Creates a [LocalMediaManager] for the given package. */
+ fun create(packageName: String): LocalMediaManager {
+ return InfoMediaManager(context, packageName, null, localBluetoothManager).run {
+ LocalMediaManager(context, localBluetoothManager, this, packageName)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index aee7a46..90054d6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -41,7 +41,6 @@
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
@@ -56,14 +55,11 @@
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import com.android.settingslib.Utils;
-import com.android.settingslib.media.LocalMediaManager;
-import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaOutputSliceConstants;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.QSMediaBrowser;
-import com.android.systemui.util.Assert;
import com.android.systemui.util.concurrency.DelayableExecutor;
import org.jetbrains.annotations.NotNull;
@@ -77,7 +73,6 @@
*/
public class MediaControlPanel {
private static final String TAG = "MediaControlPanel";
- @Nullable private final LocalMediaManager mLocalMediaManager;
// Button IDs for QS controls
static final int[] ACTION_IDS = {
@@ -100,7 +95,6 @@
private MediaSession.Token mToken;
private MediaController mController;
private int mBackgroundColor;
- private MediaDevice mDevice;
protected ComponentName mServiceComponent;
private boolean mIsRegistered = false;
private List<KeyFrames> mKeyFrames;
@@ -113,7 +107,6 @@
public static final String MEDIA_PREFERENCE_KEY = "browser_components";
private SharedPreferences mSharedPrefs;
private boolean mCheckedForResumption = false;
- private boolean mIsRemotePlayback;
private QSMediaBrowser mQSMediaBrowser;
private final MediaController.Callback mSessionCallback = new MediaController.Callback() {
@@ -122,7 +115,6 @@
Log.d(TAG, "session destroyed");
mController.unregisterCallback(mSessionCallback);
clearControls();
- makeInactive();
}
@Override
public void onPlaybackStateChanged(PlaybackState state) {
@@ -130,31 +122,6 @@
if (s == PlaybackState.STATE_NONE) {
Log.d(TAG, "playback state change will trigger resumption, state=" + state);
clearControls();
- makeInactive();
- }
- }
- };
-
- private final LocalMediaManager.DeviceCallback mDeviceCallback =
- new LocalMediaManager.DeviceCallback() {
- @Override
- public void onDeviceListUpdate(List<MediaDevice> devices) {
- if (mLocalMediaManager == null) {
- return;
- }
- MediaDevice currentDevice = mLocalMediaManager.getCurrentConnectedDevice();
- // Check because this can be called several times while changing devices
- if (mDevice == null || !mDevice.equals(currentDevice)) {
- mDevice = currentDevice;
- updateDevice(mDevice);
- }
- }
-
- @Override
- public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
- if (mDevice == null || !mDevice.equals(device)) {
- mDevice = device;
- updateDevice(mDevice);
}
}
};
@@ -162,16 +129,13 @@
/**
* Initialize a new control panel
* @param context
- * @param routeManager Manager used to listen for device change events.
* @param foregroundExecutor foreground executor
* @param backgroundExecutor background executor, used for processing artwork
* @param activityStarter activity starter
*/
- public MediaControlPanel(Context context, @Nullable LocalMediaManager routeManager,
- Executor foregroundExecutor, DelayableExecutor backgroundExecutor,
- ActivityStarter activityStarter) {
+ public MediaControlPanel(Context context, Executor foregroundExecutor,
+ DelayableExecutor backgroundExecutor, ActivityStarter activityStarter) {
mContext = context;
- mLocalMediaManager = routeManager;
mForegroundExecutor = foregroundExecutor;
mBackgroundExecutor = backgroundExecutor;
mActivityStarter = activityStarter;
@@ -183,7 +147,7 @@
if (mSeekBarObserver != null) {
mSeekBarViewModel.getProgress().removeObserver(mSeekBarObserver);
}
- makeInactive();
+ mSeekBarViewModel.onDestroy();
}
private void loadDimens() {
@@ -318,30 +282,67 @@
artistText.setText(data.getArtist());
// Transfer chip
- if (mLocalMediaManager != null) {
- mViewHolder.getSeamless().setVisibility(View.VISIBLE);
- setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
- setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
- updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
- mViewHolder.getSeamless().setOnClickListener(v -> {
- final Intent intent = new Intent()
- .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
- .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
- mController.getPackageName())
- .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
- mActivityStarter.startActivity(intent, false, true /* dismissShade */,
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- });
- } else {
- Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName);
- }
+ mViewHolder.getSeamless().setVisibility(View.VISIBLE);
+ setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
+ setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
+ mViewHolder.getSeamless().setOnClickListener(v -> {
+ final Intent intent = new Intent()
+ .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
+ .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+ mController.getPackageName())
+ .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
+ mActivityStarter.startActivity(intent, false, true /* dismissShade */,
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ });
+ final boolean isRemotePlayback;
PlaybackInfo playbackInfo = mController.getPlaybackInfo();
if (playbackInfo != null) {
- mIsRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
+ isRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
} else {
Log.d(TAG, "PlaybackInfo was null. Defaulting to local playback.");
- mIsRemotePlayback = false;
+ isRemotePlayback = false;
}
+
+ ImageView iconView = mViewHolder.getSeamlessIcon();
+ TextView deviceName = mViewHolder.getSeamlessText();
+
+ // Update the outline color
+ RippleDrawable bkgDrawable = (RippleDrawable) mViewHolder.getSeamless().getBackground();
+ GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0);
+ rect.setStroke(2, deviceName.getCurrentTextColor());
+ rect.setColor(Color.TRANSPARENT);
+
+ if (isRemotePlayback) {
+ mViewHolder.getSeamless().setEnabled(false);
+ // TODO(b/156875717): setEnabled should cause the alpha to change.
+ mViewHolder.getSeamless().setAlpha(0.38f);
+ iconView.setImageResource(R.drawable.ic_hardware_speaker);
+ iconView.setVisibility(View.VISIBLE);
+ deviceName.setText(R.string.media_seamless_remote_device);
+ } else if (data.getDevice() != null && data.getDevice().getIcon() != null
+ && data.getDevice().getName() != null) {
+ mViewHolder.getSeamless().setEnabled(true);
+ mViewHolder.getSeamless().setAlpha(1f);
+ Drawable icon = data.getDevice().getIcon();
+ iconView.setVisibility(View.VISIBLE);
+
+ if (icon instanceof AdaptiveIcon) {
+ AdaptiveIcon aIcon = (AdaptiveIcon) icon;
+ aIcon.setBackgroundColor(mBackgroundColor);
+ iconView.setImageDrawable(aIcon);
+ } else {
+ iconView.setImageDrawable(icon);
+ }
+ deviceName.setText(data.getDevice().getName());
+ } else {
+ // Reset to default
+ Log.w(TAG, "device is null. Not binding output chip.");
+ mViewHolder.getSeamless().setEnabled(true);
+ mViewHolder.getSeamless().setAlpha(1f);
+ iconView.setVisibility(View.GONE);
+ deviceName.setText(com.android.internal.R.string.ext_media_seamless_action);
+ }
+
List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact();
// Media controls
int i = 0;
@@ -382,8 +383,6 @@
// Set up long press menu
// TODO: b/156036025 bring back media guts
- makeActive();
-
// Update both constraint sets to regenerate the animation.
mViewHolder.getPlayer().updateState(R.id.collapsed, collapsedSet);
mViewHolder.getPlayer().updateState(R.id.expanded, expandedSet);
@@ -515,60 +514,6 @@
}
/**
- * Update the current device information
- * @param device device information to display
- */
- private void updateDevice(MediaDevice device) {
- mForegroundExecutor.execute(() -> {
- updateChipInternal(device);
- });
- }
-
- private void updateChipInternal(MediaDevice device) {
- if (mViewHolder == null) {
- return;
- }
- ImageView iconView = mViewHolder.getSeamlessIcon();
- TextView deviceName = mViewHolder.getSeamlessText();
-
- // Update the outline color
- LinearLayout viewLayout = (LinearLayout) mViewHolder.getSeamless();
- RippleDrawable bkgDrawable = (RippleDrawable) viewLayout.getBackground();
- GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0);
- rect.setStroke(2, deviceName.getCurrentTextColor());
- rect.setColor(Color.TRANSPARENT);
-
- if (mIsRemotePlayback) {
- mViewHolder.getSeamless().setEnabled(false);
- mViewHolder.getSeamless().setAlpha(0.38f);
- iconView.setImageResource(R.drawable.ic_hardware_speaker);
- iconView.setVisibility(View.VISIBLE);
- deviceName.setText(R.string.media_seamless_remote_device);
- } else if (device != null) {
- mViewHolder.getSeamless().setEnabled(true);
- mViewHolder.getSeamless().setAlpha(1f);
- Drawable icon = device.getIcon();
- iconView.setVisibility(View.VISIBLE);
-
- if (icon instanceof AdaptiveIcon) {
- AdaptiveIcon aIcon = (AdaptiveIcon) icon;
- aIcon.setBackgroundColor(mBackgroundColor);
- iconView.setImageDrawable(aIcon);
- } else {
- iconView.setImageDrawable(icon);
- }
- deviceName.setText(device.getName());
- } else {
- // Reset to default
- Log.d(TAG, "device is null. Not binding output chip.");
- mViewHolder.getSeamless().setEnabled(true);
- mViewHolder.getSeamless().setAlpha(1f);
- iconView.setVisibility(View.GONE);
- deviceName.setText(com.android.internal.R.string.ext_media_seamless_action);
- }
- }
-
- /**
* Puts controls into a resumption state if possible, or calls removePlayer if no component was
* found that could resume playback
*/
@@ -642,27 +587,6 @@
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
- private void makeActive() {
- Assert.isMainThread();
- if (!mIsRegistered) {
- if (mLocalMediaManager != null) {
- mLocalMediaManager.registerCallback(mDeviceCallback);
- mLocalMediaManager.startScan();
- }
- mIsRegistered = true;
- }
- }
-
- private void makeInactive() {
- Assert.isMainThread();
- if (mIsRegistered) {
- if (mLocalMediaManager != null) {
- mLocalMediaManager.stopScan();
- mLocalMediaManager.unregisterCallback(mDeviceCallback);
- }
- mIsRegistered = false;
- }
- }
/**
* Verify that we can connect to the given component with a MediaBrowser, and if so, add that
* component to the list of resumption components
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 85965d0..41d4110 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -34,7 +34,8 @@
val actionsToShowInCompact: List<Int>,
val packageName: String?,
val token: MediaSession.Token?,
- val clickIntent: PendingIntent?
+ val clickIntent: PendingIntent?,
+ val device: MediaDeviceData?
)
/** State of a media action. */
@@ -43,3 +44,9 @@
val intent: PendingIntent?,
val contentDescription: CharSequence?
)
+
+/** State of the media device. */
+data class MediaDeviceData(
+ val icon: Drawable?,
+ val name: String?
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
new file mode 100644
index 0000000..cce9838
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.media
+
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Combines updates from [MediaDataManager] with [MediaDeviceManager].
+ */
+@Singleton
+class MediaDataCombineLatest @Inject constructor(
+ private val dataSource: MediaDataManager,
+ private val deviceSource: MediaDeviceManager
+) {
+ private val listeners: MutableSet<MediaDataManager.Listener> = mutableSetOf()
+ private val entries: MutableMap<String, Pair<MediaData?, MediaDeviceData?>> = mutableMapOf()
+
+ init {
+ dataSource.addListener(object : MediaDataManager.Listener {
+ override fun onMediaDataLoaded(key: String, data: MediaData) {
+ entries[key] = data to entries[key]?.second
+ update(key)
+ }
+ override fun onMediaDataRemoved(key: String) {
+ remove(key)
+ }
+ })
+ deviceSource.addListener(object : MediaDeviceManager.Listener {
+ override fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) {
+ entries[key] = entries[key]?.first to data
+ update(key)
+ }
+ override fun onKeyRemoved(key: String) {
+ remove(key)
+ }
+ })
+ }
+
+ /**
+ * Add a listener for [MediaData] changes that has been combined with latest [MediaDeviceData].
+ */
+ fun addListener(listener: MediaDataManager.Listener) = listeners.add(listener)
+
+ /**
+ * Remove a listener registered with addListener.
+ */
+ fun removeListener(listener: MediaDataManager.Listener) = listeners.remove(listener)
+
+ private fun update(key: String) {
+ val (entry, device) = entries[key] ?: null to null
+ if (entry != null && device != null) {
+ val data = entry.copy(device = device)
+ listeners.forEach {
+ it.onMediaDataLoaded(key, data)
+ }
+ }
+ }
+
+ private fun remove(key: String) {
+ entries.remove(key)?.let {
+ listeners.forEach {
+ it.onMediaDataRemoved(key)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index f950d41..8cbe3ec 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -55,7 +55,19 @@
private const val SATURATION_MULTIPLIER = 0.8f
private val LOADING = MediaData(false, 0, null, null, null, null, null,
- emptyList(), emptyList(), null, null, null)
+ emptyList(), emptyList(), null, null, null, null)
+
+fun isMediaNotification(sbn: StatusBarNotification): Boolean {
+ if (!sbn.notification.hasMediaSession()) {
+ return false
+ }
+ val notificationStyle = sbn.notification.notificationStyle
+ if (Notification.DecoratedMediaCustomViewStyle::class.java.equals(notificationStyle) ||
+ Notification.MediaStyle::class.java.equals(notificationStyle)) {
+ return true
+ }
+ return false
+}
/**
* A class that facilitates management and loading of Media Data, ready for binding.
@@ -72,7 +84,7 @@
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
- if (isMediaNotification(sbn)) {
+ if (Utils.useQsMediaPlayer(context) && isMediaNotification(sbn)) {
if (!mediaEntries.containsKey(key)) {
mediaEntries.put(key, LOADING)
}
@@ -204,7 +216,7 @@
foregroundExecutor.execute {
onMediaDataLoaded(key, MediaData(true, bgColor, app, smallIconDrawable, artist, song,
artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token,
- notif.contentIntent))
+ notif.contentIntent, null))
}
}
@@ -270,21 +282,6 @@
}
}
- private fun isMediaNotification(sbn: StatusBarNotification): Boolean {
- if (!Utils.useQsMediaPlayer(context)) {
- return false
- }
- if (!sbn.notification.hasMediaSession()) {
- return false
- }
- val notificationStyle = sbn.notification.notificationStyle
- if (Notification.DecoratedMediaCustomViewStyle::class.java.equals(notificationStyle) ||
- Notification.MediaStyle::class.java.equals(notificationStyle)) {
- return true
- }
- return false
- }
-
/**
* Are there any media notifications active?
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
new file mode 100644
index 0000000..2d16e29
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.content.Context
+import android.service.notification.StatusBarNotification
+import com.android.settingslib.media.LocalMediaManager
+import com.android.settingslib.media.MediaDevice
+import com.android.systemui.dagger.qualifiers.Main
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Provides information about the route (ie. device) where playback is occurring.
+ */
+@Singleton
+class MediaDeviceManager @Inject constructor(
+ private val context: Context,
+ private val localMediaManagerFactory: LocalMediaManagerFactory,
+ private val featureFlag: MediaFeatureFlag,
+ @Main private val fgExecutor: Executor
+) {
+ private val listeners: MutableSet<Listener> = mutableSetOf()
+ private val entries: MutableMap<String, Token> = mutableMapOf()
+
+ /**
+ * Add a listener for changes to the media route (ie. device).
+ */
+ fun addListener(listener: Listener) = listeners.add(listener)
+
+ /**
+ * Remove a listener that has been registered with addListener.
+ */
+ fun removeListener(listener: Listener) = listeners.remove(listener)
+
+ fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
+ if (featureFlag.enabled && isMediaNotification(sbn)) {
+ var tok = entries[key]
+ if (tok == null) {
+ tok = Token(key, localMediaManagerFactory.create(sbn.packageName))
+ entries[key] = tok
+ tok.start()
+ }
+ } else {
+ onNotificationRemoved(key)
+ }
+ }
+
+ fun onNotificationRemoved(key: String) {
+ val token = entries.remove(key)
+ token?.stop()
+ token?.let {
+ listeners.forEach {
+ it.onKeyRemoved(key)
+ }
+ }
+ }
+
+ private fun processDevice(key: String, device: MediaDevice?) {
+ val data = MediaDeviceData(device?.icon, device?.name)
+ listeners.forEach {
+ it.onMediaDeviceChanged(key, data)
+ }
+ }
+
+ interface Listener {
+ /** Called when the route has changed for a given notification. */
+ fun onMediaDeviceChanged(key: String, data: MediaDeviceData?)
+ /** Called when the notification was removed. */
+ fun onKeyRemoved(key: String)
+ }
+
+ private inner class Token(
+ val key: String,
+ val localMediaManager: LocalMediaManager
+ ) : LocalMediaManager.DeviceCallback {
+ private var current: MediaDevice? = null
+ set(value) {
+ if (value != field) {
+ field = value
+ processDevice(key, value)
+ }
+ }
+ fun start() {
+ localMediaManager.registerCallback(this)
+ localMediaManager.startScan()
+ current = localMediaManager.getCurrentConnectedDevice()
+ }
+ fun stop() {
+ localMediaManager.stopScan()
+ localMediaManager.unregisterCallback(this)
+ }
+ override fun onDeviceListUpdate(devices: List<MediaDevice>?) = fgExecutor.execute {
+ current = localMediaManager.getCurrentConnectedDevice()
+ }
+ override fun onSelectedDeviceStateChanged(device: MediaDevice, state: Int) {
+ fgExecutor.execute {
+ current = device
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt b/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt
new file mode 100644
index 0000000..75eb33d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.media
+
+import android.content.Context
+import com.android.systemui.util.Utils
+import javax.inject.Inject
+
+/**
+ * Provides access to the current value of the feature flag.
+ */
+class MediaFeatureFlag @Inject constructor(private val context: Context) {
+ val enabled
+ get() = Utils.useQsMediaPlayer(context)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 6b1c520..3e7661a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -26,6 +26,7 @@
import android.view.ViewGroupOverlay
import com.android.systemui.Interpolators
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
@@ -46,7 +47,8 @@
private val keyguardStateController: KeyguardStateController,
private val bypassController: KeyguardBypassController,
private val mediaViewManager: MediaViewManager,
- private val mediaMeasurementProvider: MediaMeasurementManager
+ private val mediaMeasurementProvider: MediaMeasurementManager,
+ private val notifLockscreenUserManager: NotificationLockscreenUserManager
) {
/**
* The root overlay of the hierarchy. This is where the media notification is attached to
@@ -56,7 +58,7 @@
private var rootOverlay: ViewGroupOverlay? = null
private lateinit var currentState: MediaState
private val mediaCarousel
- get() = mediaViewManager.mediaCarousel
+ get() = mediaViewManager.mediaCarousel
private var animationStartState: MediaState? = null
private var statusbarState: Int = statusBarStateController.state
private var animator = ValueAnimator.ofFloat(0.0f, 1.0f).apply {
@@ -136,9 +138,9 @@
*
* @return the hostView associated with this location
*/
- fun register(mediaObject: MediaHost) : ViewGroup {
+ fun register(mediaObject: MediaHost): ViewGroup {
val viewHost = createUniqueObjectHost(mediaObject)
- mediaObject.hostView = viewHost;
+ mediaObject.hostView = viewHost
mediaHosts[mediaObject.location] = mediaObject
if (mediaObject.location == desiredLocation) {
// In case we are overriding a view that is already visible, make sure we attach it
@@ -155,7 +157,7 @@
private fun createUniqueObjectHost(host: MediaHost): UniqueObjectHostView {
val viewHost = UniqueObjectHostView(context)
viewHost.measurementCache = mediaMeasurementProvider.obtainCache(host)
- viewHost.onMeasureListener = { input ->
+ viewHost.onMeasureListener = { input ->
if (host.location == desiredLocation) {
// Measurement of the currently active player is happening, Let's make
// sure the player width is up to date
@@ -215,8 +217,8 @@
applyTargetStateIfNotAnimating()
} else if (animate) {
animator.cancel()
- if (currentAttachmentLocation == IN_OVERLAY
- || !previousHost.hostView.isAttachedToWindow) {
+ if (currentAttachmentLocation == IN_OVERLAY ||
+ !previousHost.hostView.isAttachedToWindow) {
// Let's animate to the new position, starting from the current position
// We also go in here in case the view was detached, since the bounds wouldn't
// be correct anymore
@@ -237,10 +239,10 @@
@MediaLocation currentLocation: Int,
@MediaLocation previousLocation: Int
): Boolean {
- if (currentLocation == LOCATION_QQS
- && previousLocation == LOCATION_LOCKSCREEN
- && (statusBarStateController.leaveOpenOnKeyguardHide()
- || statusbarState == StatusBarState.SHADE_LOCKED)) {
+ if (currentLocation == LOCATION_QQS &&
+ previousLocation == LOCATION_LOCKSCREEN &&
+ (statusBarStateController.leaveOpenOnKeyguardHide() ||
+ statusbarState == StatusBarState.SHADE_LOCKED)) {
// Usually listening to the isShown is enough to determine this, but there is some
// non-trivial reattaching logic happening that will make the view not-shown earlier
return true
@@ -251,10 +253,9 @@
private fun adjustAnimatorForTransition(desiredLocation: Int, previousLocation: Int) {
val (animDuration, delay) = getAnimationParams(previousLocation, desiredLocation)
animator.apply {
- duration = animDuration
+ duration = animDuration
startDelay = delay
}
-
}
private fun getAnimationParams(previousLocation: Int, desiredLocation: Int): Pair<Long, Long> {
@@ -262,8 +263,8 @@
var delay = 0L
if (previousLocation == LOCATION_LOCKSCREEN && desiredLocation == LOCATION_QQS) {
// Going to the full shade, let's adjust the animation duration
- if (statusbarState == StatusBarState.SHADE
- && keyguardStateController.isKeyguardFadingAway) {
+ if (statusbarState == StatusBarState.SHADE &&
+ keyguardStateController.isKeyguardFadingAway) {
delay = keyguardStateController.keyguardFadingAwayDelay
}
animDuration = StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE.toLong()
@@ -301,12 +302,12 @@
/**
* @return true if this transformation is guided by an external progress like a finger
*/
- private fun isCurrentlyInGuidedTransformation() : Boolean {
+ private fun isCurrentlyInGuidedTransformation(): Boolean {
return getTransformationProgress() >= 0
}
/**
- * @return the current transformation progress if we're in a guided transformation and -1
+ * @return the current transformation progress if we're in a guided transformation and -1
* otherwise
*/
private fun getTransformationProgress(): Float {
@@ -377,19 +378,20 @@
}
private fun isTransitionRunning(): Boolean {
- return isCurrentlyInGuidedTransformation() && getTransformationProgress() != 1.0f
- || animator.isRunning
+ return isCurrentlyInGuidedTransformation() && getTransformationProgress() != 1.0f ||
+ animator.isRunning
}
@MediaLocation
- private fun calculateLocation() : Int {
- val onLockscreen = (!bypassController.bypassEnabled
- && (statusbarState == StatusBarState.KEYGUARD
- || statusbarState == StatusBarState.FULLSCREEN_USER_SWITCHER))
+ private fun calculateLocation(): Int {
+ val onLockscreen = (!bypassController.bypassEnabled &&
+ (statusbarState == StatusBarState.KEYGUARD ||
+ statusbarState == StatusBarState.FULLSCREEN_USER_SWITCHER))
+ val allowedOnLockscreen = notifLockscreenUserManager.shouldShowLockscreenNotifications()
return when {
qsExpansion > 0.0f && !onLockscreen -> LOCATION_QS
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
- onLockscreen -> LOCATION_LOCKSCREEN
+ onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN
else -> LOCATION_QQS
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
index 8db9dcc..17e8404 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
@@ -6,9 +6,6 @@
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import android.widget.LinearLayout
-import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.media.InfoMediaManager
-import com.android.settingslib.media.LocalMediaManager
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -30,10 +27,9 @@
private val context: Context,
@Main private val foregroundExecutor: Executor,
@Background private val backgroundExecutor: DelayableExecutor,
- private val localBluetoothManager: LocalBluetoothManager?,
private val visualStabilityManager: VisualStabilityManager,
private val activityStarter: ActivityStarter,
- mediaManager: MediaDataManager
+ mediaManager: MediaDataCombineLatest
) {
private var playerWidth: Int = 0
private var playerWidthPlusPadding: Int = 0
@@ -42,7 +38,7 @@
val mediaCarousel: HorizontalScrollView
private val mediaContent: ViewGroup
private val mediaPlayers: MutableMap<String, MediaControlPanel> = mutableMapOf()
- private val visualStabilityCallback : VisualStabilityManager.Callback
+ private val visualStabilityCallback: VisualStabilityManager.Callback
private var activeMediaIndex: Int = 0
private var needsReordering: Boolean = false
private var scrollIntoCurrentMedia: Int = 0
@@ -151,15 +147,8 @@
private fun updateView(key: String, data: MediaData) {
var existingPlayer = mediaPlayers[key]
if (existingPlayer == null) {
- // Set up listener for device changes
- // TODO: integrate with MediaTransferManager?
- val imm = InfoMediaManager(context, data.packageName,
- null /* notification */, localBluetoothManager)
- val routeManager = LocalMediaManager(context, localBluetoothManager,
- imm, data.packageName)
-
- existingPlayer = MediaControlPanel(context, routeManager, foregroundExecutor,
- backgroundExecutor, activityStarter)
+ existingPlayer = MediaControlPanel(context, foregroundExecutor, backgroundExecutor,
+ activityStarter)
existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context),
mediaContent))
mediaPlayers[key] = existingPlayer
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index b08124b..06821cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -78,7 +78,22 @@
val progress: LiveData<Progress>
get() = _progress
private var controller: MediaController? = null
+ set(value) {
+ if (field?.sessionToken != value?.sessionToken) {
+ field?.unregisterCallback(callback)
+ value?.registerCallback(callback)
+ field = value
+ }
+ }
private var playbackState: PlaybackState? = null
+ private var callback = object : MediaController.Callback() {
+ override fun onPlaybackStateChanged(state: PlaybackState) {
+ playbackState = state
+ if (shouldPollPlaybackPosition()) {
+ checkPlaybackPosition()
+ }
+ }
+ }
/** Listening state (QS open or closed) is used to control polling of progress. */
var listening = true
@@ -95,6 +110,9 @@
@WorkerThread
fun onSeek(position: Long) {
controller?.transportControls?.seekTo(position)
+ // Invalidate the cached playbackState to avoid the thumb jumping back to the previous
+ // position.
+ playbackState = null
}
/**
@@ -125,12 +143,23 @@
*/
@AnyThread
fun clearController() = bgExecutor.execute {
+ controller = null
+ playbackState = null
_data = _data.copy(enabled = false)
}
+ /**
+ * Call to clean up any resources.
+ */
+ @AnyThread
+ fun onDestroy() {
+ controller = null
+ playbackState = null
+ }
+
@AnyThread
private fun checkPlaybackPosition(): Runnable = bgExecutor.executeDelayed({
- val duration = _data?.duration ?: -1
+ val duration = _data.duration ?: -1
val currentPosition = playbackState?.computePosition(duration.toLong())?.toInt()
if (currentPosition != null && _data.elapsedTime != currentPosition) {
_data = _data.copy(elapsedTime = currentPosition)
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 1982227..69bad80 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -21,6 +21,7 @@
import static android.provider.Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS;
import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS;
import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACTIONS;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ALLOW_TIMEOUT;
@@ -68,6 +69,7 @@
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
@@ -220,6 +222,29 @@
// Hide without an animation.
getWindow().setExitTransition(null);
+
+ initAccessibility();
+ }
+
+ private void initAccessibility() {
+ getWindow().getDecorView().setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ String label = getResources().getString(R.string.pip_menu_title);
+ info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, label));
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle args) {
+ if (action == ACTION_CLICK && mMenuState == MENU_STATE_CLOSE) {
+ Message m = Message.obtain();
+ m.what = PipMenuActivityController.MESSAGE_SHOW_MENU;
+ sendMessage(m, "Could not notify controller to show PIP menu");
+ }
+ return super.performAccessibilityAction(host, action, args);
+ }
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
index cf1bc7d..1ed98c0 100644
--- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
@@ -119,7 +119,7 @@
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 0fa1f55..8ed69d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -53,6 +53,7 @@
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.MediaDataManager;
+import com.android.systemui.media.MediaDeviceManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -218,7 +219,8 @@
KeyguardBypassController keyguardBypassController,
@Main DelayableExecutor mainExecutor,
DeviceConfigProxy deviceConfig,
- MediaDataManager mediaDataManager) {
+ MediaDataManager mediaDataManager,
+ MediaDeviceManager mediaDeviceManager) {
mContext = context;
mMediaArtworkProcessor = mediaArtworkProcessor;
mKeyguardBypassController = keyguardBypassController;
@@ -239,11 +241,13 @@
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
mediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn());
+ mediaDeviceManager.onNotificationAdded(entry.getKey(), entry.getSbn());
}
@Override
public void onPreEntryUpdated(NotificationEntry entry) {
mediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn());
+ mediaDeviceManager.onNotificationAdded(entry.getKey(), entry.getSbn());
}
@Override
@@ -264,6 +268,7 @@
int reason) {
onNotificationRemoved(entry.getKey());
mediaDataManager.onNotificationRemoved(entry.getKey());
+ mediaDeviceManager.onNotificationRemoved(entry.getKey());
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 7aae724..d3819e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -37,6 +37,7 @@
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
+import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.NotificationShadeWindowController
import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.phone.ScrimController
@@ -60,6 +61,7 @@
private val choreographer: Choreographer,
private val wallpaperManager: WallpaperManager,
private val notificationShadeWindowController: NotificationShadeWindowController,
+ private val dozeParameters: DozeParameters,
dumpManager: DumpManager
) : PanelExpansionListener, Dumpable {
companion object {
@@ -206,9 +208,12 @@
keyguardAnimator?.cancel()
keyguardAnimator = ValueAnimator.ofFloat(1f, 0f).apply {
- duration = keyguardStateController.keyguardFadingAwayDuration
+ // keyguardStateController.keyguardFadingAwayDuration might be zero when unlock by
+ // fingerprint due to there is no window container, see AppTransition#goodToGo.
+ // We use DozeParameters.wallpaperFadeOutDuration as an alternative.
+ duration = dozeParameters.wallpaperFadeOutDuration
startDelay = keyguardStateController.keyguardFadingAwayDelay
- interpolator = Interpolators.DECELERATE_QUINT
+ interpolator = Interpolators.FAST_OUT_SLOW_IN
addUpdateListener { animation: ValueAnimator ->
wakeAndUnlockBlurRadius =
blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index 8c9ce50..ac2a9c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -24,6 +24,7 @@
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.MediaDataManager;
+import com.android.systemui.media.MediaDeviceManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.ActionClickLogger;
import com.android.systemui.statusbar.CommandQueue;
@@ -101,7 +102,8 @@
KeyguardBypassController keyguardBypassController,
@Main DelayableExecutor mainExecutor,
DeviceConfigProxy deviceConfigProxy,
- MediaDataManager mediaDataManager) {
+ MediaDataManager mediaDataManager,
+ MediaDeviceManager mediaDeviceManager) {
return new NotificationMediaManager(
context,
statusBarLazy,
@@ -111,7 +113,8 @@
keyguardBypassController,
mainExecutor,
deviceConfigProxy,
- mediaDataManager);
+ mediaDataManager,
+ mediaDeviceManager);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index d647124..adb51a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -151,6 +151,16 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NotificationEntryManager state:");
+ pw.println(" mAllNotifications=");
+ if (mAllNotifications.size() == 0) {
+ pw.println("null");
+ } else {
+ int i = 0;
+ for (NotificationEntry entry : mAllNotifications) {
+ dumpEntry(pw, " ", i, entry);
+ i++;
+ }
+ }
pw.print(" mPendingNotifications=");
if (mPendingNotifications.size() == 0) {
pw.println("null");
@@ -350,8 +360,8 @@
private final NotificationHandler mNotifListener = new NotificationHandler() {
@Override
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
- final boolean isUpdate = mActiveNotifications.containsKey(sbn.getKey());
- if (isUpdate) {
+ final boolean isUpdateToInflatedNotif = mActiveNotifications.containsKey(sbn.getKey());
+ if (isUpdateToInflatedNotif) {
updateNotification(sbn, rankingMap);
} else {
addNotification(sbn, rankingMap);
@@ -442,16 +452,12 @@
}
if (!lifetimeExtended) {
// At this point, we are guaranteed the notification will be removed
+ abortExistingInflation(key, "removeNotification");
mAllNotifications.remove(pendingEntry);
+ mLeakDetector.trackGarbage(pendingEntry);
}
}
- }
-
- if (!lifetimeExtended) {
- abortExistingInflation(key, "removeNotification");
- }
-
- if (entry != null) {
+ } else {
// If a manager needs to keep the notification around for whatever reason, we
// keep the notification
boolean entryDismissed = entry.isRowDismissed();
@@ -469,6 +475,8 @@
if (!lifetimeExtended) {
// At this point, we are guaranteed the notification will be removed
+ abortExistingInflation(key, "removeNotification");
+ mAllNotifications.remove(entry);
// Ensure any managers keeping the lifetime extended stop managing the entry
cancelLifetimeExtension(entry);
@@ -477,13 +485,10 @@
entry.removeRow();
}
- mAllNotifications.remove(entry);
-
// Let's remove the children if this was a summary
handleGroupSummaryRemoved(key);
removeVisibleNotification(key);
updateNotifications("removeNotificationInternal");
- mLeakDetector.trackGarbage(entry);
removedByUser |= entryDismissed;
mLogger.logNotifRemoved(entry.getKey(), removedByUser);
@@ -497,6 +502,7 @@
for (NotifCollectionListener listener : mNotifCollectionListeners) {
listener.onEntryCleanUp(entry);
}
+ mLeakDetector.trackGarbage(entry);
}
}
}
@@ -556,21 +562,26 @@
Ranking ranking = new Ranking();
rankingMap.getRanking(key, ranking);
- NotificationEntry entry = new NotificationEntry(
- notification,
- ranking,
- mFgsFeatureController.isForegroundServiceDismissalEnabled(),
- SystemClock.uptimeMillis());
+ NotificationEntry entry = mPendingNotifications.get(key);
+ if (entry != null) {
+ entry.setSbn(notification);
+ } else {
+ entry = new NotificationEntry(
+ notification,
+ ranking,
+ mFgsFeatureController.isForegroundServiceDismissalEnabled(),
+ SystemClock.uptimeMillis());
+ mAllNotifications.add(entry);
+ mLeakDetector.trackInstance(entry);
+
+ for (NotifCollectionListener listener : mNotifCollectionListeners) {
+ listener.onEntryInit(entry);
+ }
+ }
+
for (NotifCollectionListener listener : mNotifCollectionListeners) {
listener.onEntryBind(entry, notification);
}
- mAllNotifications.add(entry);
-
- mLeakDetector.trackInstance(entry);
-
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryInit(entry);
- }
// Construct the expanded view.
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
@@ -581,7 +592,6 @@
mInflationCallback);
}
- abortExistingInflation(key, "addNotification");
mPendingNotifications.put(key, entry);
mLogger.logNotifAdded(entry.getKey());
for (NotificationEntryListener listener : mNotificationEntryListeners) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index a3621b6..d7365e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -61,6 +61,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.dump.LogBufferEulogizer;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.notification.collection.coalescer.CoalescedEvent;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
@@ -126,6 +127,7 @@
private final IStatusBarService mStatusBarService;
private final FeatureFlags mFeatureFlags;
private final NotifCollectionLogger mLogger;
+ private final LogBufferEulogizer mEulogizer;
private final Map<String, NotificationEntry> mNotificationSet = new ArrayMap<>();
private final Collection<NotificationEntry> mReadOnlyNotificationSet =
@@ -146,10 +148,12 @@
IStatusBarService statusBarService,
DumpManager dumpManager,
FeatureFlags featureFlags,
- NotifCollectionLogger logger) {
+ NotifCollectionLogger logger,
+ LogBufferEulogizer logBufferEulogizer) {
Assert.isMainThread();
mStatusBarService = statusBarService;
mLogger = logger;
+ mEulogizer = logBufferEulogizer;
dumpManager.registerDumpable(TAG, this);
mFeatureFlags = featureFlags;
}
@@ -223,7 +227,8 @@
requireNonNull(stats);
if (entry != mNotificationSet.get(entry.getKey())) {
- throw new IllegalStateException("Invalid entry: " + entry.getKey());
+ throw mEulogizer.record(
+ new IllegalStateException("Invalid entry: " + entry.getKey()));
}
if (entry.getDismissState() == DISMISSED) {
@@ -367,8 +372,11 @@
final NotificationEntry entry = mNotificationSet.get(sbn.getKey());
if (entry == null) {
- throw new IllegalStateException("No notification to remove with key " + sbn.getKey());
+ throw mEulogizer.record(
+ new IllegalStateException("No notification to remove with key "
+ + sbn.getKey()));
}
+
entry.mCancellationReason = reason;
tryRemoveNotification(entry);
applyRanking(rankingMap);
@@ -390,11 +398,11 @@
if (entry == null) {
// A new notification!
entry = new NotificationEntry(sbn, ranking, SystemClock.uptimeMillis());
+ mEventQueue.add(new InitEntryEvent(entry));
mEventQueue.add(new BindEntryEvent(entry, sbn));
mNotificationSet.put(sbn.getKey(), entry);
mLogger.logNotifPosted(sbn.getKey());
- mEventQueue.add(new InitEntryEvent(entry));
mEventQueue.add(new EntryAddedEvent(entry));
} else {
@@ -426,12 +434,15 @@
*/
private boolean tryRemoveNotification(NotificationEntry entry) {
if (mNotificationSet.get(entry.getKey()) != entry) {
- throw new IllegalStateException("No notification to remove with key " + entry.getKey());
+ throw mEulogizer.record(
+ new IllegalStateException("No notification to remove with key "
+ + entry.getKey()));
}
if (!isCanceled(entry)) {
- throw new IllegalStateException("Cannot remove notification " + entry.getKey()
- + ": has not been marked for removal");
+ throw mEulogizer.record(
+ new IllegalStateException("Cannot remove notification " + entry.getKey()
+ + ": has not been marked for removal"));
}
if (isDismissedByUser(entry)) {
@@ -501,11 +512,11 @@
checkForReentrantCall();
if (!entry.mLifetimeExtenders.remove(extender)) {
- throw new IllegalStateException(
+ throw mEulogizer.record(new IllegalStateException(
String.format(
"Cannot end lifetime extension for extender \"%s\" (%s)",
extender.getName(),
- extender));
+ extender)));
}
mLogger.logLifetimeExtensionEnded(
@@ -581,11 +592,11 @@
checkForReentrantCall();
if (!entry.mDismissInterceptors.remove(interceptor)) {
- throw new IllegalStateException(
+ throw mEulogizer.record(new IllegalStateException(
String.format(
"Cannot end dismiss interceptor for interceptor \"%s\" (%s)",
interceptor.getName(),
- interceptor));
+ interceptor)));
}
if (!isDismissIntercepted(entry)) {
@@ -608,7 +619,7 @@
private void checkForReentrantCall() {
if (mAmDispatchingToOtherCode) {
- throw new IllegalStateException("Reentrant call detected");
+ throw mEulogizer.record(new IllegalStateException("Reentrant call detected"));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index dc0b802..bab2686 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -74,11 +74,14 @@
val aRank = a.ranking.rank
val bRank = b.ranking.rank
+ val aIsFsn = a.isColorizedForegroundService()
+ val bIsFsn = b.isColorizedForegroundService()
+
val aPersonType = a.getPeopleNotificationType()
val bPersonType = b.getPeopleNotificationType()
- val aMedia = isImportantMedia(a)
- val bMedia = isImportantMedia(b)
+ val aMedia = a.isImportantMedia()
+ val bMedia = b.isImportantMedia()
val aSystemMax = a.isSystemMax()
val bSystemMax = b.isSystemMax()
@@ -92,7 +95,7 @@
aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
// Provide consistent ranking with headsUpManager
aHeadsUp -> headsUpManager.compare(a, b)
-
+ aIsFsn != bIsFsn -> if (aIsFsn) -1 else 1
usePeopleFiltering && aPersonType != bPersonType ->
peopleNotificationIdentifier.compareTo(aPersonType, bPersonType)
// Upsort current media notification.
@@ -106,11 +109,6 @@
}
}
- private fun isImportantMedia(entry: NotificationEntry): Boolean {
- val importance = entry.ranking.importance
- return entry.key == mediaManager.mediaNotificationKey && importance > IMPORTANCE_MIN
- }
-
fun updateRanking(
newRankingMap: RankingMap?,
entries: Collection<NotificationEntry>,
@@ -153,15 +151,12 @@
@PriorityBucket
private fun getBucketForEntry(entry: NotificationEntry): Int {
val isHeadsUp = entry.isRowHeadsUp
- val isMedia = isImportantMedia(entry)
+ val isMedia = entry.isImportantMedia()
val isSystemMax = entry.isSystemMax()
return when {
- entry.sbn.notification.isForegroundService && entry.sbn.notification.isColorized ->
- BUCKET_FOREGROUND_SERVICE
- usePeopleFiltering && entry.getPeopleNotificationType() != TYPE_NON_PERSON ->
- BUCKET_PEOPLE
- isHeadsUp || isMedia || isSystemMax || entry.isHighPriority() ->
- BUCKET_ALERTING
+ entry.isColorizedForegroundService() -> BUCKET_FOREGROUND_SERVICE
+ usePeopleFiltering && entry.isConversation() -> BUCKET_PEOPLE
+ isHeadsUp || isMedia || isSystemMax || entry.isHighPriority() -> BUCKET_ALERTING
else -> BUCKET_SILENT
}
}
@@ -190,6 +185,11 @@
}
}
+ private fun NotificationEntry.isImportantMedia() =
+ key == mediaManager.mediaNotificationKey && ranking.importance > IMPORTANCE_MIN
+
+ private fun NotificationEntry.isConversation() = getPeopleNotificationType() != TYPE_NON_PERSON
+
private fun NotificationEntry.getPeopleNotificationType() =
peopleNotificationIdentifier.getPeopleNotificationType(sbn, ranking)
@@ -198,10 +198,12 @@
}
// Convenience functions
-private fun NotificationEntry.isSystemMax(): Boolean {
- return importance >= IMPORTANCE_HIGH && sbn.isSystemNotification()
-}
+private fun NotificationEntry.isSystemMax() =
+ importance >= IMPORTANCE_HIGH && sbn.isSystemNotification()
-private fun StatusBarNotification.isSystemNotification(): Boolean {
- return "android" == packageName || "com.android.systemui" == packageName
+private fun StatusBarNotification.isSystemNotification() =
+ "android" == packageName || "com.android.systemui" == packageName
+
+private fun NotificationEntry.isColorizedForegroundService() = sbn.notification.run {
+ isForegroundService && isColorized && importance > IMPORTANCE_MIN
}
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 e9849ec..9925909 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
@@ -64,6 +64,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
/**
* A frame layout containing the actual payload of the notification, including the contracted,
@@ -518,9 +519,12 @@
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
updateVisibility();
- if (visibility != VISIBLE) {
+ if (visibility != VISIBLE && !mOnContentViewInactiveListeners.isEmpty()) {
// View is no longer visible so all content views are inactive.
- for (Runnable r : mOnContentViewInactiveListeners.values()) {
+ // Clone list as runnables may modify the list of listeners
+ ArrayList<Runnable> listeners = new ArrayList<>(
+ mOnContentViewInactiveListeners.values());
+ for (Runnable r : listeners) {
r.run();
}
mOnContentViewInactiveListeners.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
index 66c07bd..1dc828b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
@@ -192,9 +192,9 @@
private void bindName() {
TextView name = findViewById(R.id.name);
Bundle extras = mSbn.getNotification().extras;
- String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE);
+ CharSequence nameString = extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE, "");
if (TextUtils.isEmpty(nameString)) {
- nameString = extras.getString(Notification.EXTRA_TITLE);
+ nameString = extras.getCharSequence(Notification.EXTRA_TITLE, "");
}
name.setText(nameString);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 3db4b6f..e33cc60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5983,6 +5983,7 @@
// ANIMATION_TYPE_ADD
new AnimationFilter()
+ .animateAlpha()
.animateHeight()
.animateTopInset()
.animateY()
@@ -5991,6 +5992,7 @@
// ANIMATION_TYPE_REMOVE
new AnimationFilter()
+ .animateAlpha()
.animateHeight()
.animateTopInset()
.animateY()
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 a065b74..2a4475b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -46,6 +46,8 @@
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.media.MediaData;
+import com.android.systemui.media.MediaDataManager;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.screenrecord.RecordingController;
@@ -80,14 +82,14 @@
*/
public class PhoneStatusBarPolicy
implements BluetoothController.Callback,
- CommandQueue.Callbacks,
- RotationLockControllerCallback,
- Listener,
- ZenModeController.Callback,
- DeviceProvisionedListener,
- KeyguardStateController.Callback,
- LocationController.LocationChangeCallback,
- RecordingController.RecordingStateChangeCallback {
+ CommandQueue.Callbacks,
+ RotationLockControllerCallback,
+ Listener,
+ ZenModeController.Callback,
+ DeviceProvisionedListener,
+ KeyguardStateController.Callback,
+ LocationController.LocationChangeCallback,
+ RecordingController.RecordingStateChangeCallback, MediaDataManager.Listener {
private static final String TAG = "PhoneStatusBarPolicy";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -108,6 +110,7 @@
private final String mSlotLocation;
private final String mSlotSensorsOff;
private final String mSlotScreenRecord;
+ private final String mSlotMedia;
private final int mDisplayId;
private final SharedPreferences mSharedPreferences;
private final DateFormatUtil mDateFormatUtil;
@@ -135,6 +138,7 @@
private final SensorPrivacyController mSensorPrivacyController;
private final RecordingController mRecordingController;
private final RingerModeTracker mRingerModeTracker;
+ private final MediaDataManager mMediaDataManager;
private boolean mZenVisible;
private boolean mVolumeVisible;
@@ -159,6 +163,7 @@
SensorPrivacyController sensorPrivacyController, IActivityManager iActivityManager,
AlarmManager alarmManager, UserManager userManager,
RecordingController recordingController,
+ MediaDataManager mediaDataManager,
@Nullable TelecomManager telecomManager, @DisplayId int displayId,
@Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil,
RingerModeTracker ringerModeTracker) {
@@ -185,6 +190,7 @@
mUiBgExecutor = uiBgExecutor;
mTelecomManager = telecomManager;
mRingerModeTracker = ringerModeTracker;
+ mMediaDataManager = mediaDataManager;
mSlotCast = resources.getString(com.android.internal.R.string.status_bar_cast);
mSlotHotspot = resources.getString(com.android.internal.R.string.status_bar_hotspot);
@@ -202,6 +208,7 @@
mSlotSensorsOff = resources.getString(com.android.internal.R.string.status_bar_sensors_off);
mSlotScreenRecord = resources.getString(
com.android.internal.R.string.status_bar_screen_record);
+ mSlotMedia = resources.getString(com.android.internal.R.string.status_bar_media);
mDisplayId = displayId;
mSharedPreferences = sharedPreferences;
@@ -280,6 +287,11 @@
mIconController.setIconVisibility(mSlotSensorsOff,
mSensorPrivacyController.isSensorPrivacyEnabled());
+ // play/pause icon when media is active
+ mIconController.setIcon(mSlotMedia, R.drawable.stat_sys_media,
+ mResources.getString(R.string.accessibility_media_active));
+ mIconController.setIconVisibility(mSlotMedia, mMediaDataManager.hasActiveMedia());
+
// screen record
mIconController.setIcon(mSlotScreenRecord, R.drawable.stat_sys_screen_record, null);
mIconController.setIconVisibility(mSlotScreenRecord, false);
@@ -296,6 +308,7 @@
mSensorPrivacyController.addCallback(mSensorPrivacyListener);
mLocationController.addCallback(this);
mRecordingController.addCallback(this);
+ mMediaDataManager.addListener(this);
mCommandQueue.addCallback(this);
}
@@ -700,4 +713,18 @@
if (DEBUG) Log.d(TAG, "screenrecord: hiding icon");
mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
}
+
+ @Override
+ public void onMediaDataLoaded(String key, MediaData data) {
+ updateMediaIcon();
+ }
+
+ @Override
+ public void onMediaDataRemoved(String key) {
+ updateMediaIcon();
+ }
+
+ private void updateMediaIcon() {
+ mIconController.setIconVisibility(mSlotMedia, mMediaDataManager.hasActiveMedia());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/io/Files.java b/packages/SystemUI/src/com/android/systemui/util/io/Files.java
new file mode 100644
index 0000000..7d633a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/io/Files.java
@@ -0,0 +1,58 @@
+/*
+ * 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.util.io;
+
+import androidx.annotation.NonNull;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.LinkOption;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Wrapper around {@link java.nio.file.Files} that can be mocked in tests.
+ */
+@Singleton
+public class Files {
+ @Inject
+ public Files() { }
+
+ /** See {@link java.nio.file.Files#newBufferedWriter} */
+ public BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException {
+ return java.nio.file.Files.newBufferedWriter(path, StandardCharsets.UTF_8, options);
+ }
+
+ /** See {@link java.nio.file.Files#lines} */
+ public Stream<String> lines(Path path) throws IOException {
+ return java.nio.file.Files.lines(path);
+ }
+
+ /** See {@link java.nio.file.Files#readAttributes} */
+ public <A extends BasicFileAttributes> A readAttributes(
+ @NonNull Path path,
+ @NonNull Class<A> type,
+ @NonNull LinkOption... options) throws IOException {
+ return java.nio.file.Files.readAttributes(path, type, options);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java b/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java
index 6fef59f..6f32cc1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java
@@ -37,4 +37,7 @@
/** @see android.os.SystemClock#currentThreadTimeMillis() */
long currentThreadTimeMillis();
+
+ /** @see System#currentTimeMillis() */
+ long currentTimeMillis();
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java b/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java
index f0c7014..4e508cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java
@@ -42,4 +42,9 @@
public long currentThreadTimeMillis() {
return android.os.SystemClock.currentThreadTimeMillis();
}
+
+ @Override
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
similarity index 90%
rename from packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
index 8d530ec..9e67eda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
@@ -32,9 +32,12 @@
import java.io.PrintWriter
@SmallTest
-class DumpManagerTest : SysuiTestCase() {
+class DumpHandlerTest : SysuiTestCase() {
- private lateinit var dumpManager: DumpManager
+ private lateinit var dumpHandler: DumpHandler
+
+ @Mock
+ private lateinit var logBufferEulogizer: LogBufferEulogizer
@Mock
private lateinit var fd: FileDescriptor
@@ -53,11 +56,13 @@
@Mock
private lateinit var buffer2: LogBuffer
+ private val dumpManager = DumpManager()
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- dumpManager = DumpManager(mContext)
+ dumpHandler = DumpHandler(mContext, dumpManager, logBufferEulogizer)
}
@Test
@@ -71,7 +76,7 @@
// WHEN some of them are dumped explicitly
val args = arrayOf("dumpable1", "dumpable3", "buffer2")
- dumpManager.dump(fd, pw, args)
+ dumpHandler.dump(fd, pw, args)
// THEN only the requested ones have their dump() method called
verify(dumpable1).dump(fd, pw, args)
@@ -91,7 +96,7 @@
// WHEN that module is dumped
val args = arrayOf("dumpable1")
- dumpManager.dump(fd, pw, args)
+ dumpHandler.dump(fd, pw, args)
// THEN its dump() method is called
verify(dumpable1).dump(fd, pw, args)
@@ -108,7 +113,7 @@
// WHEN a critical dump is requested
val args = arrayOf("--dump-priority", "CRITICAL")
- dumpManager.dump(fd, pw, args)
+ dumpHandler.dump(fd, pw, args)
// THEN all modules are dumped (but no buffers)
verify(dumpable1).dump(fd, pw, args)
@@ -127,9 +132,9 @@
dumpManager.registerBuffer("buffer1", buffer1)
dumpManager.registerBuffer("buffer2", buffer2)
- // WHEN a critical dump is requested
+ // WHEN a normal dump is requested
val args = arrayOf("--dump-priority", "NORMAL")
- dumpManager.dump(fd, pw, args)
+ dumpHandler.dump(fd, pw, args)
// THEN all buffers are dumped (but no modules)
verify(dumpable1, never()).dump(
@@ -147,4 +152,4 @@
verify(buffer1).dump(pw, 0)
verify(buffer2).dump(pw, 0)
}
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
new file mode 100644
index 0000000..cb38846
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
@@ -0,0 +1,169 @@
+/*
+ * 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.dump
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.io.FakeBasicFileAttributes
+import com.android.systemui.util.io.Files
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.io.BufferedWriter
+import java.io.ByteArrayOutputStream
+import java.io.IOException
+import java.io.OutputStreamWriter
+import java.io.PrintWriter
+import java.nio.file.LinkOption
+import java.nio.file.OpenOption
+import java.nio.file.Paths
+import java.nio.file.attribute.BasicFileAttributes
+import java.util.Arrays
+
+@SmallTest
+class LogEulogizerTest : SysuiTestCase() {
+
+ lateinit var eulogizer: LogBufferEulogizer
+
+ @Mock
+ lateinit var dumpManager: DumpManager
+
+ @Mock
+ lateinit var files: Files
+
+ private val clock = FakeSystemClock()
+
+ private val path = Paths.get("/foo/bar/baz.txt")
+ private val fileAttrs = FakeBasicFileAttributes()
+ private val fileStream = ByteArrayOutputStream()
+ private val fileWriter = BufferedWriter(OutputStreamWriter(fileStream))
+
+ private val dumpStream = ByteArrayOutputStream()
+ private val dumpWriter = PrintWriter(OutputStreamWriter(dumpStream))
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ eulogizer =
+ LogBufferEulogizer(dumpManager, clock, files, path, MIN_WRITE_GAP, MAX_READ_AGE)
+
+ Mockito.`when`(files.newBufferedWriter(eq(path), any(OpenOption::class.java)))
+ .thenReturn(fileWriter)
+
+ Mockito.`when`(
+ files.readAttributes(eq(path),
+ eq(BasicFileAttributes::class.java),
+ any(LinkOption::class.java))
+ ).thenReturn(fileAttrs)
+
+ Mockito.`when`(files.lines(eq(path))).thenReturn(Arrays.stream(FAKE_LINES))
+ }
+
+ @Test
+ fun testFileIsCreated() {
+ // GIVEN that the log file doesn't already exist
+ Mockito.`when`(
+ files.readAttributes(eq(path),
+ eq(BasicFileAttributes::class.java),
+ any(LinkOption::class.java))
+ ).thenThrow(IOException("File not found"))
+
+ // WHEN .record() is called
+ val exception = RuntimeException("Something bad happened")
+ assertEquals(exception, eulogizer.record(exception))
+
+ // THEN the buffers are dumped to the file
+ verify(dumpManager).dumpBuffers(any(PrintWriter::class.java), Mockito.anyInt())
+ assertTrue(fileStream.toString().isNotEmpty())
+ }
+
+ @Test
+ fun testExistingFileIsOverwritten() {
+ // GIVEN that the log file already exists but hasn't been modified in a while
+ fileAttrs.setLastModifiedTime(clock.currentTimeMillis() - MIN_WRITE_GAP - 20)
+
+ // WHEN .record() is called
+ val exception = RuntimeException("Something bad happened")
+ assertEquals(exception, eulogizer.record(exception))
+
+ // THEN the buffers are dumped to the file
+ verify(dumpManager).dumpBuffers(any(PrintWriter::class.java), Mockito.anyInt())
+ assertTrue(fileStream.toString().isNotEmpty())
+ }
+
+ @Test
+ fun testYoungFileIsNotOverwritten() {
+ // GIVEN that the log file has been modified recently
+ fileAttrs.setLastModifiedTime(clock.currentTimeMillis() - MIN_WRITE_GAP + 7)
+
+ // WHEN .record() is called
+ val exception = RuntimeException("Something bad happened")
+ assertEquals(exception, eulogizer.record(exception))
+
+ // THEN the file isn't written to
+ verify(dumpManager, never()).dumpBuffers(any(PrintWriter::class.java), Mockito.anyInt())
+ assertTrue(fileStream.toString().isEmpty())
+ }
+
+ @Test
+ fun testRecentFileIsDumped() {
+ // GIVEN that the log file was written to "recently"
+ fileAttrs.setLastModifiedTime(clock.currentTimeMillis() - MAX_READ_AGE + 7)
+
+ // WHEN we're asked to eulogize the log
+ eulogizer.readEulogyIfPresent(dumpWriter)
+ dumpWriter.close()
+
+ // THEN the log file is written to the output stream
+ verify(files).lines(eq(path))
+ assertTrue(dumpStream.toString().isNotBlank())
+ }
+
+ @Test
+ fun testOldFileIsNotDumped() {
+ // GIVEN that the log file was written to a long time ago
+ fileAttrs.setLastModifiedTime(clock.currentTimeMillis() - MAX_READ_AGE - 7)
+
+ // WHEN we're asked to eulogize the log
+ eulogizer.readEulogyIfPresent(dumpWriter)
+ dumpWriter.close()
+
+ // THEN the log file is NOT written to the output stream
+ verify(files, never()).lines(eq(path))
+ assertTrue(dumpStream.toString().isEmpty())
+ }
+}
+
+private const val MIN_WRITE_GAP = 10L
+private const val MAX_READ_AGE = 100L
+
+private val FAKE_LINES =
+ arrayOf(
+ "First line",
+ "Second line",
+ "Third line"
+ )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
new file mode 100644
index 0000000..9aee11e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.media
+
+import android.testing.AndroidTestingRunner
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.stack.MediaHeaderView
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class KeyguardMediaControllerTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var mediaHost: MediaHost
+ @Mock
+ private lateinit var bypassController: KeyguardBypassController
+ @Mock
+ private lateinit var statusBarStateController: SysuiStatusBarStateController
+ @Mock
+ private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
+ @Mock
+ private lateinit var mediaHeaderView: MediaHeaderView
+ @Captor
+ private lateinit var visibilityListener: ArgumentCaptor<((Boolean) -> Unit)>
+ @JvmField @Rule
+ val mockito = MockitoJUnit.rule()
+ private lateinit var keyguardMediaController: KeyguardMediaController
+
+ @Before
+ fun setup() {
+ keyguardMediaController = KeyguardMediaController(mediaHost, bypassController,
+ statusBarStateController, notificationLockscreenUserManager)
+ }
+
+ @Test
+ fun testAttach_hiddenWhenHostIsHidden() {
+ `when`(mediaHost.visible).thenReturn(false)
+ triggerVisibilityListener()
+
+ verify(mediaHeaderView).visibility = eq(GONE)
+ }
+ @Test
+ fun testAttach_visibleOnKeyguard() {
+ `when`(mediaHost.visible).thenReturn(true)
+ `when`(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ `when`(notificationLockscreenUserManager.shouldShowLockscreenNotifications())
+ .thenReturn(true)
+ triggerVisibilityListener()
+
+ verify(mediaHeaderView).visibility = eq(VISIBLE)
+ }
+ @Test
+ fun testAttach_hiddenOnKeyguard_whenNotificationsAreHidden() {
+ `when`(mediaHost.visible).thenReturn(true)
+ `when`(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ `when`(notificationLockscreenUserManager.shouldShowLockscreenNotifications())
+ .thenReturn(false)
+ triggerVisibilityListener()
+
+ verify(mediaHeaderView).visibility = eq(GONE)
+ }
+
+ private fun triggerVisibilityListener() {
+ keyguardMediaController.attach(mediaHeaderView)
+ verify(mediaHost).visibleChangedListener = visibilityListener.capture()
+ visibilityListener.value.invoke(true)
+ }
+}
\ 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 60d15a8..e8fb41a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -18,6 +18,8 @@
import android.content.res.ColorStateList
import android.graphics.Color
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.RippleDrawable
import android.media.MediaMetadata
import android.media.session.MediaSession
import android.media.session.PlaybackState
@@ -104,7 +106,7 @@
activityStarter = mock(ActivityStarter::class.java)
- player = MediaControlPanel(context, null, fgExecutor, bgExecutor, activityStarter)
+ player = MediaControlPanel(context, fgExecutor, bgExecutor, activityStarter)
// Mock out a view holder for the player to attach to.
holder = mock(PlayerViewHolder::class.java)
@@ -129,6 +131,9 @@
artistText = TextView(context)
whenever(holder.artistText).thenReturn(artistText)
seamless = FrameLayout(context)
+ val seamlessBackground = mock(RippleDrawable::class.java)
+ seamless.setBackground(seamlessBackground)
+ whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
whenever(holder.seamless).thenReturn(seamless)
seamlessIcon = ImageView(context)
whenever(holder.seamlessIcon).thenReturn(seamlessIcon)
@@ -176,7 +181,7 @@
@Test
fun bindWhenUnattached() {
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, null, null)
+ emptyList(), PACKAGE, null, null, MediaDeviceData(null, DEVICE_NAME))
player.bind(state)
assertThat(player.isPlaying()).isFalse()
}
@@ -185,7 +190,8 @@
fun bindText() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null)
+ emptyList(), PACKAGE, session.getSessionToken(), null,
+ MediaDeviceData(null, DEVICE_NAME))
player.bind(state)
assertThat(appName.getText()).isEqualTo(APP)
assertThat(titleText.getText()).isEqualTo(TITLE)
@@ -196,7 +202,8 @@
fun bindBackgroundColor() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null)
+ emptyList(), PACKAGE, session.getSessionToken(), null,
+ MediaDeviceData(null, DEVICE_NAME))
player.bind(state)
assertThat(background.getBackgroundTintList()).isEqualTo(ColorStateList.valueOf(BG_COLOR))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
new file mode 100644
index 0000000..64a180f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Color;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class MediaDataCombineLatestTest extends SysuiTestCase {
+
+ private static final String KEY = "TEST_KEY";
+ private static final String APP = "APP";
+ private static final String PACKAGE = "PKG";
+ private static final int BG_COLOR = Color.RED;
+ private static final String ARTIST = "ARTIST";
+ private static final String TITLE = "TITLE";
+ private static final String DEVICE_NAME = "DEVICE_NAME";
+
+ private MediaDataCombineLatest mManager;
+
+ @Mock private MediaDataManager mDataSource;
+ @Mock private MediaDeviceManager mDeviceSource;
+ @Mock private MediaDataManager.Listener mListener;
+
+ private MediaDataManager.Listener mDataListener;
+ private MediaDeviceManager.Listener mDeviceListener;
+
+ private MediaData mMediaData;
+ private MediaDeviceData mDeviceData;
+
+ @Before
+ public void setUp() {
+ mDataSource = mock(MediaDataManager.class);
+ mDeviceSource = mock(MediaDeviceManager.class);
+ mListener = mock(MediaDataManager.Listener.class);
+
+ mManager = new MediaDataCombineLatest(mDataSource, mDeviceSource);
+
+ mDataListener = captureDataListener();
+ mDeviceListener = captureDeviceListener();
+
+ mManager.addListener(mListener);
+
+ mMediaData = new MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null,
+ new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null);
+ mDeviceData = new MediaDeviceData(null, DEVICE_NAME);
+ }
+
+ @Test
+ public void eventNotEmittedWithoutDevice() {
+ // WHEN data source emits an event without device data
+ mDataListener.onMediaDataLoaded(KEY, mMediaData);
+ // THEN an event isn't emitted
+ verify(mListener, never()).onMediaDataLoaded(eq(KEY), any());
+ }
+
+ @Test
+ public void eventNotEmittedWithoutMedia() {
+ // WHEN device source emits an event without media data
+ mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
+ // THEN an event isn't emitted
+ verify(mListener, never()).onMediaDataLoaded(eq(KEY), any());
+ }
+
+ @Test
+ public void emitEventAfterDeviceFirst() {
+ // GIVEN that a device event has already been received
+ mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
+ // WHEN media event is received
+ mDataListener.onMediaDataLoaded(KEY, mMediaData);
+ // THEN the listener receives a combined event
+ ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
+ verify(mListener).onMediaDataLoaded(eq(KEY), captor.capture());
+ assertThat(captor.getValue().getDevice()).isNotNull();
+ }
+
+ @Test
+ public void emitEventAfterMediaFirst() {
+ // GIVEN that media event has already been received
+ mDataListener.onMediaDataLoaded(KEY, mMediaData);
+ // WHEN device event is received
+ mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
+ // THEN the listener receives a combined event
+ ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
+ verify(mListener).onMediaDataLoaded(eq(KEY), captor.capture());
+ assertThat(captor.getValue().getDevice()).isNotNull();
+ }
+
+ @Test
+ public void mediaDataRemoved() {
+ // WHEN media data is removed without first receiving device or data
+ mDataListener.onMediaDataRemoved(KEY);
+ // THEN a removed event isn't emitted
+ verify(mListener, never()).onMediaDataRemoved(eq(KEY));
+ }
+
+ @Test
+ public void mediaDataRemovedAfterMediaEvent() {
+ mDataListener.onMediaDataLoaded(KEY, mMediaData);
+ mDataListener.onMediaDataRemoved(KEY);
+ verify(mListener).onMediaDataRemoved(eq(KEY));
+ }
+
+ @Test
+ public void mediaDataRemovedAfterDeviceEvent() {
+ mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
+ mDataListener.onMediaDataRemoved(KEY);
+ verify(mListener).onMediaDataRemoved(eq(KEY));
+ }
+
+ private MediaDataManager.Listener captureDataListener() {
+ ArgumentCaptor<MediaDataManager.Listener> captor = ArgumentCaptor.forClass(
+ MediaDataManager.Listener.class);
+ verify(mDataSource).addListener(captor.capture());
+ return captor.getValue();
+ }
+
+ private MediaDeviceManager.Listener captureDeviceListener() {
+ ArgumentCaptor<MediaDeviceManager.Listener> captor = ArgumentCaptor.forClass(
+ MediaDeviceManager.Listener.class);
+ verify(mDeviceSource).addListener(captor.capture());
+ return captor.getValue();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
new file mode 100644
index 0000000..ac6b5f6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -0,0 +1,195 @@
+/*
+ * 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.media
+
+import android.app.Notification
+import android.media.MediaMetadata
+import android.media.session.MediaSession
+import android.media.session.PlaybackState
+import android.os.Process
+import android.service.notification.StatusBarNotification
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+
+import com.android.settingslib.media.LocalMediaManager
+import com.android.settingslib.media.MediaDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.After
+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.any
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+private const val KEY = "TEST_KEY"
+private const val PACKAGE = "PKG"
+private const val SESSION_KEY = "SESSION_KEY"
+private const val SESSION_ARTIST = "SESSION_ARTIST"
+private const val SESSION_TITLE = "SESSION_TITLE"
+private const val DEVICE_NAME = "DEVICE_NAME"
+
+private fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+public class MediaDeviceManagerTest : SysuiTestCase() {
+
+ private lateinit var manager: MediaDeviceManager
+
+ @Mock private lateinit var lmmFactory: LocalMediaManagerFactory
+ @Mock private lateinit var lmm: LocalMediaManager
+ @Mock private lateinit var featureFlag: MediaFeatureFlag
+ private lateinit var fakeExecutor: FakeExecutor
+
+ @Mock private lateinit var device: MediaDevice
+ private lateinit var session: MediaSession
+ private lateinit var metadataBuilder: MediaMetadata.Builder
+ private lateinit var playbackBuilder: PlaybackState.Builder
+ private lateinit var notifBuilder: Notification.Builder
+ private lateinit var sbn: StatusBarNotification
+
+ @Before
+ fun setup() {
+ lmmFactory = mock(LocalMediaManagerFactory::class.java)
+ lmm = mock(LocalMediaManager::class.java)
+ device = mock(MediaDevice::class.java)
+ whenever(device.name).thenReturn(DEVICE_NAME)
+ whenever(lmmFactory.create(PACKAGE)).thenReturn(lmm)
+ whenever(lmm.getCurrentConnectedDevice()).thenReturn(device)
+ featureFlag = mock(MediaFeatureFlag::class.java)
+ whenever(featureFlag.enabled).thenReturn(true)
+
+ fakeExecutor = FakeExecutor(FakeSystemClock())
+
+ manager = MediaDeviceManager(context, lmmFactory, featureFlag, fakeExecutor)
+
+ // Create a media sesssion and notification for testing.
+ metadataBuilder = MediaMetadata.Builder().apply {
+ putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
+ putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
+ }
+ playbackBuilder = PlaybackState.Builder().apply {
+ setState(PlaybackState.STATE_PAUSED, 6000L, 1f)
+ setActions(PlaybackState.ACTION_PLAY)
+ }
+ session = MediaSession(context, SESSION_KEY).apply {
+ setMetadata(metadataBuilder.build())
+ setPlaybackState(playbackBuilder.build())
+ }
+ session.setActive(true)
+ notifBuilder = Notification.Builder(context, "NONE").apply {
+ setContentTitle(SESSION_TITLE)
+ setContentText(SESSION_ARTIST)
+ setSmallIcon(android.R.drawable.ic_media_pause)
+ setStyle(Notification.MediaStyle().setMediaSession(session.getSessionToken()))
+ }
+ sbn = StatusBarNotification(PACKAGE, PACKAGE, 0, "TAG", Process.myUid(), 0, 0,
+ notifBuilder.build(), Process.myUserHandle(), 0)
+ }
+
+ @After
+ fun tearDown() {
+ session.release()
+ }
+
+ @Test
+ fun removeUnknown() {
+ manager.onNotificationRemoved("unknown")
+ }
+
+ @Test
+ fun addNotification() {
+ manager.onNotificationAdded(KEY, sbn)
+ verify(lmmFactory).create(PACKAGE)
+ }
+
+ @Test
+ fun featureDisabled() {
+ whenever(featureFlag.enabled).thenReturn(false)
+ manager.onNotificationAdded(KEY, sbn)
+ verify(lmmFactory, never()).create(PACKAGE)
+ }
+
+ @Test
+ fun addAndRemoveNotification() {
+ manager.onNotificationAdded(KEY, sbn)
+ manager.onNotificationRemoved(KEY)
+ verify(lmm).unregisterCallback(any())
+ }
+
+ @Test
+ fun deviceListUpdate() {
+ val listener = mock(MediaDeviceManager.Listener::class.java)
+ manager.addListener(listener)
+ manager.onNotificationAdded(KEY, sbn)
+ val deviceCallback = captureCallback()
+ // WHEN the device list changes
+ deviceCallback.onDeviceListUpdate(mutableListOf(device))
+ assertThat(fakeExecutor.runAllReady()).isEqualTo(1)
+ // THEN the update is dispatched to the listener
+ val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
+ verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture())
+ val data = captor.getValue()
+ assertThat(data.name).isEqualTo(DEVICE_NAME)
+ }
+
+ @Test
+ fun selectedDeviceStateChanged() {
+ val listener = mock(MediaDeviceManager.Listener::class.java)
+ manager.addListener(listener)
+ manager.onNotificationAdded(KEY, sbn)
+ val deviceCallback = captureCallback()
+ // WHEN the selected device changes state
+ deviceCallback.onSelectedDeviceStateChanged(device, 1)
+ assertThat(fakeExecutor.runAllReady()).isEqualTo(1)
+ // THEN the update is dispatched to the listener
+ val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
+ verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture())
+ val data = captor.getValue()
+ assertThat(data.name).isEqualTo(DEVICE_NAME)
+ }
+
+ @Test
+ fun listenerReceivesKeyRemoved() {
+ manager.onNotificationAdded(KEY, sbn)
+ val listener = mock(MediaDeviceManager.Listener::class.java)
+ manager.addListener(listener)
+ // WHEN the notification is removed
+ manager.onNotificationRemoved(KEY)
+ // THEN the listener receives key removed event
+ verify(listener).onKeyRemoved(eq(KEY))
+ }
+
+ fun captureCallback(): LocalMediaManager.DeviceCallback {
+ val captor = ArgumentCaptor.forClass(LocalMediaManager.DeviceCallback::class.java)
+ verify(lmm).registerCallback(captor.capture())
+ return captor.getValue()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
index 1bbf24f..19e15b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
@@ -18,6 +18,7 @@
import android.media.MediaMetadata
import android.media.session.MediaController
+import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -35,9 +36,12 @@
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.any
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
+import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@@ -61,12 +65,15 @@
}
@Mock private lateinit var mockController: MediaController
@Mock private lateinit var mockTransport: MediaController.TransportControls
+ private val token1 = MediaSession.Token(1, null)
+ private val token2 = MediaSession.Token(2, null)
@Before
fun setUp() {
fakeExecutor = FakeExecutor(FakeSystemClock())
viewModel = SeekBarViewModel(fakeExecutor)
mockController = mock(MediaController::class.java)
+ whenever(mockController.sessionToken).thenReturn(token1)
mockTransport = mock(MediaController.TransportControls::class.java)
// LiveData to run synchronously
@@ -79,6 +86,42 @@
}
@Test
+ fun updateRegistersCallback() {
+ viewModel.updateController(mockController)
+ verify(mockController).registerCallback(any())
+ }
+
+ @Test
+ fun updateSecondTimeDoesNotRepeatRegistration() {
+ viewModel.updateController(mockController)
+ viewModel.updateController(mockController)
+ verify(mockController, times(1)).registerCallback(any())
+ }
+
+ @Test
+ fun updateDifferentControllerUnregistersCallback() {
+ viewModel.updateController(mockController)
+ viewModel.updateController(mock(MediaController::class.java))
+ verify(mockController).unregisterCallback(any())
+ }
+
+ @Test
+ fun updateDifferentControllerRegistersCallback() {
+ viewModel.updateController(mockController)
+ val controller2 = mock(MediaController::class.java)
+ whenever(controller2.sessionToken).thenReturn(token2)
+ viewModel.updateController(controller2)
+ verify(controller2).registerCallback(any())
+ }
+
+ @Test
+ fun updateToNullUnregistersCallback() {
+ viewModel.updateController(mockController)
+ viewModel.updateController(null)
+ verify(mockController).unregisterCallback(any())
+ }
+
+ @Test
fun updateDurationWithPlayback() {
// GIVEN that the duration is contained within the metadata
val duration = 12000L
@@ -375,6 +418,26 @@
}
@Test
+ fun playbackChangeQueuesPollTask() {
+ viewModel.updateController(mockController)
+ val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java)
+ verify(mockController).registerCallback(captor.capture())
+ val callback = captor.value
+ // WHEN the callback receives an new state
+ val state = PlaybackState.Builder().run {
+ setState(PlaybackState.STATE_PLAYING, 100L, 1f)
+ build()
+ }
+ callback.onPlaybackStateChanged(state)
+ with(fakeExecutor) {
+ advanceClockToNext()
+ runAllReady()
+ }
+ // THEN an update task is queued
+ assertThat(fakeExecutor.numPending()).isEqualTo(1)
+ }
+
+ @Test
fun clearSeekBar() {
// GIVEN that the duration is contained within the metadata
val metadata = MediaMetadata.Builder().run {
@@ -399,4 +462,20 @@
// THEN the seek bar is disabled
assertThat(viewModel.progress.value!!.enabled).isFalse()
}
+
+ @Test
+ fun clearSeekBarUnregistersCallback() {
+ viewModel.updateController(mockController)
+ viewModel.clearController()
+ fakeExecutor.runAllReady()
+ verify(mockController).unregisterCallback(any())
+ }
+
+ @Test
+ fun destroyUnregistersCallback() {
+ viewModel.updateController(mockController)
+ viewModel.onDestroy()
+ fakeExecutor.runAllReady()
+ verify(mockController).unregisterCallback(any())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index c46ac47..e889dad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator
import com.android.systemui.statusbar.phone.BiometricUnlockController
+import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.NotificationShadeWindowController
import com.android.systemui.statusbar.policy.KeyguardStateController
import org.junit.Before
@@ -67,6 +68,7 @@
@Mock private lateinit var shadeAnimation: NotificationShadeDepthController.DepthAnimation
@Mock private lateinit var globalActionsSpring: NotificationShadeDepthController.DepthAnimation
@Mock private lateinit var brightnessSpring: NotificationShadeDepthController.DepthAnimation
+ @Mock private lateinit var dozeParameters: DozeParameters
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
private lateinit var statusBarStateListener: StatusBarStateController.StateListener
@@ -87,7 +89,7 @@
notificationShadeDepthController = NotificationShadeDepthController(
statusBarStateController, blurUtils, biometricUnlockController,
keyguardStateController, choreographer, wallpaperManager,
- notificationShadeWindowController, dumpManager)
+ notificationShadeWindowController, dozeParameters, dumpManager)
notificationShadeDepthController.shadeSpring = shadeSpring
notificationShadeDepthController.shadeAnimation = shadeAnimation
notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index d583048..a5a5f81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -210,6 +210,28 @@
}
@Test
+ public void testAddNotification_noDuplicateEntriesCreated() {
+ // GIVEN a notification has been added
+ mEntryManager.addNotification(mSbn, mRankingMap);
+
+ // WHEN the same notification is added multiple times before the previous entry (with
+ // the same key) didn't finish inflating
+ mEntryManager.addNotification(mSbn, mRankingMap);
+ mEntryManager.addNotification(mSbn, mRankingMap);
+ mEntryManager.addNotification(mSbn, mRankingMap);
+
+ // THEN getAllNotifs() only contains exactly one notification with this key
+ int count = 0;
+ for (NotificationEntry entry : mEntryManager.getAllNotifs()) {
+ if (entry.getKey().equals(mSbn.getKey())) {
+ count++;
+ }
+ }
+ assertEquals("Should only be one entry with key=" + mSbn.getKey() + " in mAllNotifs. "
+ + "Instead there are " + count, 1, count);
+ }
+
+ @Test
public void testAddNotification_setsUserSentiment() {
mEntryManager.addNotification(mSbn, mRankingMap);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 82de4a3..ca9cc29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -34,6 +34,7 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -65,6 +66,7 @@
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.dump.LogBufferEulogizer;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent;
@@ -100,11 +102,13 @@
public class NotifCollectionTest extends SysuiTestCase {
@Mock private IStatusBarService mStatusBarService;
+ @Mock private FeatureFlags mFeatureFlags;
@Mock private NotifCollectionLogger mLogger;
+ @Mock private LogBufferEulogizer mEulogizer;
+
@Mock private GroupCoalescer mGroupCoalescer;
@Spy private RecordingCollectionListener mCollectionListener;
@Mock private CollectionReadyForBuildListener mBuildListener;
- @Mock private FeatureFlags mFeatureFlags;
@Spy private RecordingLifetimeExtender mExtender1 = new RecordingLifetimeExtender("Extender1");
@Spy private RecordingLifetimeExtender mExtender2 = new RecordingLifetimeExtender("Extender2");
@@ -136,13 +140,16 @@
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(true);
when(mFeatureFlags.isNewNotifPipelineEnabled()).thenReturn(true);
+ when(mEulogizer.record(any(Exception.class))).thenAnswer(i -> i.getArguments()[0]);
+
mListenerInOrder = inOrder(mCollectionListener);
mCollection = new NotifCollection(
mStatusBarService,
mock(DumpManager.class),
mFeatureFlags,
- mLogger);
+ mLogger,
+ mEulogizer);
mCollection.attach(mGroupCoalescer);
mCollection.addCollectionListener(mCollectionListener);
mCollection.setBuildListener(mBuildListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
index 9f47f4a..1c47131 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
@@ -38,9 +38,11 @@
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.google.common.truth.Truth.assertThat
import dagger.Lazy
import junit.framework.Assert.assertEquals
import org.junit.Before
@@ -353,6 +355,58 @@
assertEquals(false, e.hasFinishedInitialization())
}
+ @Test
+ fun testSort_colorizedForegroundService() {
+ whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
+
+ val a = NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_HIGH)
+ .setPkg("pkg")
+ .setOpPkg("pkg")
+ .setTag("tag")
+ .setNotification(
+ Notification.Builder(mContext, "test")
+ .build())
+ .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
+ .setUser(mContext.getUser())
+ .setOverrideGroupKey("")
+ .build()
+
+ val b = NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_DEFAULT) // high priority
+ .setPkg("pkg2")
+ .setOpPkg("pkg2")
+ .setTag("tag")
+ .setNotification(mock(Notification::class.java).also { notif ->
+ whenever(notif.isForegroundService).thenReturn(true)
+ whenever(notif.isColorized).thenReturn(true)
+ })
+ .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
+ .setUser(mContext.getUser())
+ .setOverrideGroupKey("")
+ .build()
+
+ val cN = Notification.Builder(mContext, "test")
+ .setStyle(Notification.MessagingStyle(""))
+ .build()
+ val c = NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_HIGH)
+ .setPkg("pkg")
+ .setOpPkg("pkg")
+ .setTag("tag")
+ .setNotification(cN)
+ .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
+ .setUser(mContext.user)
+ .setOverrideGroupKey("")
+ .build()
+ whenever(personNotificationIdentifier.getPeopleNotificationType(a.sbn, a.ranking))
+ .thenReturn(TYPE_IMPORTANT_PERSON)
+
+ assertThat(rankingManager.updateRanking(null, listOf(a, b, c), "test"))
+ .containsExactly(b, c, a)
+ assertThat(b.bucket).isEqualTo(BUCKET_FOREGROUND_SERVICE)
+ }
+
internal class TestableNotificationRankingManager(
mediaManager: Lazy<NotificationMediaManager>,
groupManager: NotificationGroupManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index f21b1a6..545b59a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
@@ -47,6 +47,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -151,8 +152,11 @@
NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
IMPORTANCE_LOW);
mDefaultNotificationChannelSet.add(mDefaultNotificationChannel);
+ Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
+ .setContentTitle(new SpannableString("title"))
+ .build();
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
- new Notification(), UserHandle.CURRENT, null, 0);
+ n, UserHandle.CURRENT, null, 0);
mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
}
@@ -176,6 +180,23 @@
}
@Test
+ public void testBindNotification_SetsName() {
+ mInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ mChannelEditorDialogController,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mNotificationChannelSet,
+ mEntry,
+ null,
+ true,
+ false);
+ final TextView textView = mInfo.findViewById(R.id.name);
+ assertTrue(textView.getText().toString().contains("title"));
+ }
+
+ @Test
public void testBindNotification_groupSetsPackageIcon() {
mEntry.getSbn().getNotification().extras.putBoolean(EXTRA_IS_GROUP_CONVERSATION, true);
final Drawable iconDrawable = mock(Drawable.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java
new file mode 100644
index 0000000..a14d575
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.IActivityManager;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.UserManager;
+import android.telecom.TelecomManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.media.MediaDataManager;
+import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.policy.BluetoothController;
+import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.LocationController;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.RotationLockController;
+import com.android.systemui.statusbar.policy.SensorPrivacyController;
+import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.RingerModeLiveData;
+import com.android.systemui.util.RingerModeTracker;
+import com.android.systemui.util.time.DateFormatUtil;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class PhoneStatusBarPolicyTest extends SysuiTestCase {
+
+ private static final int DISPLAY_ID = 0;
+ @Mock
+ private StatusBarIconController mIconController;
+ @Mock
+ private CommandQueue mCommandQueue;
+ @Mock
+ private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private Executor mBackgroundExecutor;
+ @Mock
+ private CastController mCastController;
+ @Mock
+ private HotspotController mHotSpotController;
+ @Mock
+ private BluetoothController mBluetoothController;
+ @Mock
+ private NextAlarmController mNextAlarmController;
+ @Mock
+ private UserInfoController mUserInfoController;
+ @Mock
+ private RotationLockController mRotationLockController;
+ @Mock
+ private DataSaverController mDataSaverController;
+ @Mock
+ private ZenModeController mZenModeController;
+ @Mock
+ private DeviceProvisionedController mDeviceProvisionerController;
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private LocationController mLocationController;
+ @Mock
+ private SensorPrivacyController mSensorPrivacyController;
+ @Mock
+ private IActivityManager mIActivityManager;
+ @Mock
+ private AlarmManager mAlarmManager;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private RecordingController mRecordingController;
+ @Mock
+ private MediaDataManager mMediaDataManager;
+ @Mock
+ private TelecomManager mTelecomManager;
+ @Mock
+ private SharedPreferences mSharedPreferences;
+ @Mock
+ private DateFormatUtil mDateFormatUtil;
+ @Mock
+ private RingerModeTracker mRingerModeTracker;
+ @Mock
+ private RingerModeLiveData mRingerModeLiveData;
+ @Rule
+ public MockitoRule rule = MockitoJUnit.rule();
+ private Resources mResources;
+ private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
+
+ @Before
+ public void setup() {
+ mResources = spy(getContext().getResources());
+ mPhoneStatusBarPolicy = new PhoneStatusBarPolicy(mIconController, mCommandQueue,
+ mBroadcastDispatcher, mBackgroundExecutor, mResources, mCastController,
+ mHotSpotController, mBluetoothController, mNextAlarmController, mUserInfoController,
+ mRotationLockController, mDataSaverController, mZenModeController,
+ mDeviceProvisionerController, mKeyguardStateController, mLocationController,
+ mSensorPrivacyController, mIActivityManager, mAlarmManager, mUserManager,
+ mRecordingController, mMediaDataManager, mTelecomManager, DISPLAY_ID,
+ mSharedPreferences, mDateFormatUtil, mRingerModeTracker);
+ when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData);
+ when(mRingerModeTracker.getRingerModeInternal()).thenReturn(mRingerModeLiveData);
+ clearInvocations(mIconController);
+ }
+
+ @Test
+ public void testInit_registerMediaCallback() {
+ mPhoneStatusBarPolicy.init();
+ verify(mMediaDataManager).addListener(eq(mPhoneStatusBarPolicy));
+ }
+
+ @Test
+ public void testOnMediaDataLoaded_updatesIcon_hasMedia() {
+ String mediaSlot = mResources.getString(com.android.internal.R.string.status_bar_media);
+ when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
+ mPhoneStatusBarPolicy.onMediaDataLoaded(null, null);
+ verify(mMediaDataManager).hasActiveMedia();
+ verify(mIconController).setIconVisibility(eq(mediaSlot), eq(true));
+ }
+
+ @Test
+ public void testOnMediaDataRemoved_updatesIcon_noMedia() {
+ String mediaSlot = mResources.getString(com.android.internal.R.string.status_bar_media);
+ mPhoneStatusBarPolicy.onMediaDataRemoved(null);
+ verify(mMediaDataManager).hasActiveMedia();
+ verify(mIconController).setIconVisibility(eq(mediaSlot), eq(false));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java b/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java
new file mode 100644
index 0000000..f7a04dc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java
@@ -0,0 +1,126 @@
+/*
+ * 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.util.io;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Fake implementation of {@link BasicFileAttributes} (for use in tests)
+ */
+public class FakeBasicFileAttributes implements BasicFileAttributes {
+ private FileTime mLastModifiedTime = FileTime.from(0, TimeUnit.MILLISECONDS);
+ private FileTime mLastAccessTime = FileTime.from(0, TimeUnit.MILLISECONDS);
+ private FileTime mCreationTime = FileTime.from(0, TimeUnit.MILLISECONDS);
+ private boolean mIsRegularFile = true;
+ private boolean mIsDirectory = false;
+ private boolean mIsSymbolicLink = false;
+ private boolean mIsOther = false;
+ private long mSize = 0;
+ private Object mFileKey = null;
+
+ @Override
+ public FileTime lastModifiedTime() {
+ return mLastModifiedTime;
+ }
+
+ @Override
+ public FileTime lastAccessTime() {
+ return mLastAccessTime;
+ }
+
+ @Override
+ public FileTime creationTime() {
+ return mCreationTime;
+ }
+
+ @Override
+ public boolean isRegularFile() {
+ return mIsRegularFile;
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return mIsDirectory;
+ }
+
+ @Override
+ public boolean isSymbolicLink() {
+ return mIsSymbolicLink;
+ }
+
+ @Override
+ public boolean isOther() {
+ return mIsOther;
+ }
+
+ @Override
+ public long size() {
+ return mSize;
+ }
+
+ @Override
+ public Object fileKey() {
+ return mFileKey;
+ }
+
+ public FakeBasicFileAttributes setLastModifiedTime(long millis) {
+ mLastModifiedTime = FileTime.from(millis, TimeUnit.MILLISECONDS);
+ return this;
+ }
+
+ public FakeBasicFileAttributes setLastAccessTime(long millis) {
+ mLastAccessTime = FileTime.from(millis, TimeUnit.MILLISECONDS);
+ return this;
+ }
+
+ public FakeBasicFileAttributes setCreationTime(long millis) {
+ mCreationTime = FileTime.from(millis, TimeUnit.MILLISECONDS);
+ return this;
+ }
+
+ public FakeBasicFileAttributes setRegularFile(boolean regularFile) {
+ mIsRegularFile = regularFile;
+ return this;
+ }
+
+ public FakeBasicFileAttributes setDirectory(boolean directory) {
+ mIsDirectory = directory;
+ return this;
+ }
+
+ public FakeBasicFileAttributes setSymbolicLink(boolean symbolicLink) {
+ mIsSymbolicLink = symbolicLink;
+ return this;
+ }
+
+ public FakeBasicFileAttributes setOther(boolean other) {
+ mIsOther = other;
+ return this;
+ }
+
+ public FakeBasicFileAttributes setSize(long size) {
+ mSize = size;
+ return this;
+ }
+
+ public FakeBasicFileAttributes setFileKey(Object fileKey) {
+ mFileKey = fileKey;
+ return this;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
index 601f88e..ecfb357 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
@@ -36,8 +36,9 @@
private long mElapsedRealtime = 10000;
private long mCurrentThreadTimeMillis = 10000;
- private final List<ClockTickListener> mListeners = new ArrayList<>();
+ private long mCurrentTimeMillis = 1555555500000L;
+ private final List<ClockTickListener> mListeners = new ArrayList<>();
@Override
public long uptimeMillis() {
return mUptimeMillis;
@@ -58,10 +59,19 @@
return mCurrentThreadTimeMillis;
}
+ @Override
+ public long currentTimeMillis() {
+ return mCurrentTimeMillis;
+ }
+
public void setUptimeMillis(long uptime) {
advanceTime(uptime - mUptimeMillis);
}
+ public void setCurrentTimeMillis(long millis) {
+ mCurrentTimeMillis = millis;
+ }
+
public void advanceTime(long uptime) {
advanceTime(uptime, 0);
}
@@ -74,6 +84,7 @@
if (uptime > 0 || sleepTime > 0) {
mUptimeMillis += uptime;
mElapsedRealtime += uptime + sleepTime;
+ mCurrentTimeMillis += uptime + sleepTime;
mCurrentThreadTimeMillis += Math.ceil(uptime * 0.5);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e2a0c29..ee0f71b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -42,8 +42,8 @@
import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED;
import static android.os.storage.OnObbStateChangeListener.MOUNTED;
import static android.os.storage.OnObbStateChangeListener.UNMOUNTED;
+import static android.os.storage.StorageManager.PROP_FORCED_SCOPED_STORAGE_WHITELIST;
import static android.os.storage.StorageManager.PROP_FUSE;
-import static android.os.storage.StorageManager.PROP_LEGACY_OP_STICKY;
import static android.os.storage.StorageManager.PROP_SETTINGS_FUSE;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -914,7 +914,6 @@
refreshIsolatedStorageSettings();
}
});
- updateLegacyStorageOpSticky();
// For now, simply clone property when it changes
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
mContext.getMainExecutor(), (properties) -> {
@@ -1836,13 +1835,6 @@
}
}
- private void updateLegacyStorageOpSticky() {
- final boolean propertyValue = DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
- "legacy_storage_op_sticky", true);
- SystemProperties.set(PROP_LEGACY_OP_STICKY, propertyValue ? "true" : "false");
- }
-
private void start() {
connectStoraged();
connectVold();
@@ -4442,6 +4434,9 @@
pw.println("Isolated storage, remote feature flag: "
+ Settings.Global.getInt(cr, Settings.Global.ISOLATED_STORAGE_REMOTE, 0));
pw.println("Isolated storage, resolved: " + StorageManager.hasIsolatedStorage());
+ pw.println("Forced scoped storage app list: "
+ + DeviceConfig.getProperty(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+ PROP_FORCED_SCOPED_STORAGE_WHITELIST));
}
synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index f42e32d..35936ba 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -337,6 +337,8 @@
mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
+ TwilightManager twilightManager = getLocalService(TwilightManager.class);
+ if (twilightManager != null) mTwilightManager = twilightManager;
mLocalPowerManager =
LocalServices.getService(PowerManagerInternal.class);
initPowerSave();
@@ -381,7 +383,6 @@
com.android.internal.R.bool.config_enableCarDockHomeLaunch);
mUiModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockUiMode);
mNightModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockDayNightMode);
- mTwilightManager = getLocalService(TwilightManager.class);
final PackageManager pm = context.getPackageManager();
mTelevision = pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
|| pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
@@ -391,6 +392,8 @@
// Update the initial, static configurations.
SystemServerInitThreadPool.submit(() -> {
synchronized (mLock) {
+ TwilightManager twilightManager = getLocalService(TwilightManager.class);
+ if (twilightManager != null) mTwilightManager = twilightManager;
updateNightModeFromSettingsLocked(context, res, UserHandle.getCallingUserId());
updateSystemProperties();
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 98d662a..78e06a3 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -955,6 +955,8 @@
mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
setMicMuteFromSwitchInput();
+
+ initMinStreamVolumeWithoutModifyAudioSettings();
}
RoleObserver mRoleObserver;
@@ -1308,7 +1310,7 @@
mStreamStates[streamType].setIndex(
mStreamStates[mStreamVolumeAlias[streamType]]
.getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
- device, caller);
+ device, caller, true /*hasModifyAudioSettings*/);
}
mStreamStates[streamType].checkFixedVolumeDevices();
}
@@ -1873,13 +1875,16 @@
direction, 0 /*ignored*/,
extVolCtlr, 0 /*delay*/);
} else {
+ final boolean hasModifyAudioSettings =
+ mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED;
adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
- caller, Binder.getCallingUid());
+ caller, Binder.getCallingUid(), hasModifyAudioSettings);
}
}
private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
- String callingPackage, String caller, int uid) {
+ String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) {
if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
+ ", flags=" + flags + ", caller=" + caller
+ ", volControlStream=" + mVolumeControlStream
@@ -1933,10 +1938,12 @@
if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
}
- adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
+ adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid,
+ hasModifyAudioSettings);
}
- /** @see AudioManager#adjustStreamVolume(int, int, int) */
+ /** @see AudioManager#adjustStreamVolume(int, int, int)
+ * Part of service interface, check permissions here */
public void adjustStreamVolume(int streamType, int direction, int flags,
String callingPackage) {
if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
@@ -1944,14 +1951,17 @@
+ "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
return;
}
+ final boolean hasModifyAudioSettings =
+ mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED;
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
direction/*val1*/, flags/*val2*/, callingPackage));
adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
- Binder.getCallingUid());
+ Binder.getCallingUid(), hasModifyAudioSettings);
}
protected void adjustStreamVolume(int streamType, int direction, int flags,
- String callingPackage, String caller, int uid) {
+ String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) {
if (mUseFixedVolume) {
return;
}
@@ -2105,7 +2115,8 @@
Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
mVolumeController.postDisplaySafeVolumeWarning(flags);
} else if (!isFullVolumeDevice(device)
- && (streamState.adjustIndex(direction * step, device, caller)
+ && (streamState.adjustIndex(direction * step, device, caller,
+ hasModifyAudioSettings)
|| streamState.mIsMuted)) {
// Post message to set system volume (it in turn will post a
// message to persist).
@@ -2327,9 +2338,9 @@
}
private void onSetStreamVolume(int streamType, int index, int flags, int device,
- String caller) {
+ String caller, boolean hasModifyAudioSettings) {
final int stream = mStreamVolumeAlias[streamType];
- setStreamVolumeInt(stream, index, device, false, caller);
+ setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
// setting volume on ui sounds stream type also controls silent mode
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(stream == getUiSoundsStreamType())) {
@@ -2377,7 +2388,7 @@
continue;
}
setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage,
- Binder.getCallingUid());
+ Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
}
}
@@ -2419,7 +2430,8 @@
return AudioSystem.getMinVolumeIndexForAttributes(attr);
}
- /** @see AudioManager#setStreamVolume(int, int, int) */
+ /** @see AudioManager#setStreamVolume(int, int, int)
+ * Part of service interface, check permissions here */
public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
@@ -2442,10 +2454,13 @@
+ " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage);
return;
}
+ final boolean hasModifyAudioSettings =
+ mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED;
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
index/*val1*/, flags/*val2*/, callingPackage));
setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
- Binder.getCallingUid());
+ Binder.getCallingUid(), hasModifyAudioSettings);
}
private boolean canChangeAccessibilityVolume() {
@@ -2569,7 +2584,7 @@
}
private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
- String caller, int uid) {
+ String caller, int uid, boolean hasModifyAudioSettings) {
if (DEBUG_VOL) {
Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
+ ", calling=" + callingPackage + ")");
@@ -2660,7 +2675,7 @@
mPendingVolumeCommand = new StreamVolumeCommand(
streamType, index, flags, device);
} else {
- onSetStreamVolume(streamType, index, flags, device, caller);
+ onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings);
index = mStreamStates[streamType].getIndex(device);
}
}
@@ -2872,19 +2887,22 @@
* @param index Desired volume index of the stream
* @param device the device whose volume must be changed
* @param force If true, set the volume even if the desired volume is same
+ * @param caller
+ * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
+ * MODIFY_AUDIO_ROUTING permission
* as the current volume.
*/
private void setStreamVolumeInt(int streamType,
int index,
int device,
boolean force,
- String caller) {
+ String caller, boolean hasModifyAudioSettings) {
if (isFullVolumeDevice(device)) {
return;
}
VolumeStreamState streamState = mStreamStates[streamType];
- if (streamState.setIndex(index, device, caller) || force) {
+ if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
// Post message to set system volume (it in turn will post a message
// to persist).
sendMsg(mAudioHandler,
@@ -3417,7 +3435,7 @@
int device = vss.mIndexMap.keyAt(i);
int value = vss.mIndexMap.valueAt(i);
if (value == 0) {
- vss.setIndex(10, device, TAG);
+ vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
}
}
// Persist volume for stream ring when it is changed here
@@ -3762,7 +3780,8 @@
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int device = getDeviceForStream(streamType);
int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
- setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller);
+ setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller,
+ true /*hasModifyAudioSettings*/);
updateStreamVolumeAlias(true /*updateVolumes*/, caller);
@@ -4671,6 +4690,44 @@
return false;
}
+ /**
+ * Minimum attenuation that can be set for alarms over speaker by an application that
+ * doesn't have the MODIFY_AUDIO_SETTINGS permission.
+ */
+ protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
+
+ /**
+ * Configures the VolumeStreamState instances for minimum stream index that can be accessed
+ * without MODIFY_AUDIO_SETTINGS permission.
+ * Can only be done successfully once audio policy has finished reading its configuration files
+ * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
+ * remain at the stream min index value.
+ */
+ protected void initMinStreamVolumeWithoutModifyAudioSettings() {
+ int idx;
+ int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
+ if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
+ MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
+ deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
+ }
+ for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
+ idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
+ if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
+ < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
+ break;
+ }
+ }
+ final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
+ ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
+ : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
+ // update the VolumeStreamState for STREAM_ALARM and its aliases
+ for (int stream : mStreamVolumeAlias) {
+ if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
+ mStreamStates[stream].updateNoPermMinIndex(safeIndex);
+ }
+ }
+ }
+
/** only public for mocking/spying, do not call outside of AudioService */
@VisibleForTesting
public int getDeviceForStream(int stream) {
@@ -5335,6 +5392,8 @@
private class VolumeStreamState {
private final int mStreamType;
private int mIndexMin;
+ // min index when user doesn't have permission to change audio settings
+ private int mIndexMinNoPerm;
private int mIndexMax;
private boolean mIsMuted;
@@ -5376,6 +5435,7 @@
mStreamType = streamType;
mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
+ mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10);
@@ -5386,6 +5446,18 @@
mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
}
+ /**
+ * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
+ * @param index minimum index expressed in "UI units", i.e. no 10x factor
+ */
+ public void updateNoPermMinIndex(int index) {
+ mIndexMinNoPerm = index * 10;
+ if (mIndexMinNoPerm < mIndexMin) {
+ Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
+ mIndexMinNoPerm = mIndexMin;
+ }
+ }
+
public int observeDevicesForStream_syncVSS(boolean checkOthers) {
if (!mSystemServer.isPrivileged()) {
return AudioSystem.DEVICE_NONE;
@@ -5467,7 +5539,8 @@
continue;
}
- mIndexMap.put(device, getValidIndex(10 * index));
+ mIndexMap.put(device, getValidIndex(10 * index,
+ true /*hasModifyAudioSettings*/));
}
}
}
@@ -5555,17 +5628,20 @@
}
}
- public boolean adjustIndex(int deltaIndex, int device, String caller) {
- return setIndex(getIndex(device) + deltaIndex, device, caller);
+ public boolean adjustIndex(int deltaIndex, int device, String caller,
+ boolean hasModifyAudioSettings) {
+ return setIndex(getIndex(device) + deltaIndex, device, caller,
+ hasModifyAudioSettings);
}
- public boolean setIndex(int index, int device, String caller) {
+ public boolean setIndex(int index, int device, String caller,
+ boolean hasModifyAudioSettings) {
boolean changed;
int oldIndex;
synchronized (mSettingsLock) {
synchronized (VolumeStreamState.class) {
oldIndex = getIndex(device);
- index = getValidIndex(index);
+ index = getValidIndex(index, hasModifyAudioSettings);
if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
index = mIndexMax;
}
@@ -5585,10 +5661,12 @@
mStreamVolumeAlias[streamType] == mStreamType &&
(changed || !aliasStreamState.hasIndexForDevice(device))) {
final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
- aliasStreamState.setIndex(scaledIndex, device, caller);
+ aliasStreamState.setIndex(scaledIndex, device, caller,
+ hasModifyAudioSettings);
if (isCurrentDevice) {
aliasStreamState.setIndex(scaledIndex,
- getDeviceForStream(streamType), caller);
+ getDeviceForStream(streamType), caller,
+ hasModifyAudioSettings);
}
}
}
@@ -5678,7 +5756,7 @@
index = srcMap.valueAt(i);
index = rescaleIndex(index, srcStreamType, mStreamType);
- setIndex(index, device, caller);
+ setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
}
}
@@ -5745,9 +5823,10 @@
}
}
- private int getValidIndex(int index) {
- if (index < mIndexMin) {
- return mIndexMin;
+ private int getValidIndex(int index, boolean hasModifyAudioSettings) {
+ final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
+ if (index < indexMin) {
+ return indexMin;
} else if (mUseFixedVolume || index > mIndexMax) {
return mIndexMax;
}
@@ -5759,7 +5838,13 @@
pw.print(" Muted: ");
pw.println(mIsMuted);
pw.print(" Min: ");
- pw.println((mIndexMin + 5) / 10);
+ pw.print((mIndexMin + 5) / 10);
+ if (mIndexMin != mIndexMinNoPerm) {
+ pw.print(" w/o perm:");
+ pw.println((mIndexMinNoPerm + 5) / 10);
+ } else {
+ pw.println();
+ }
pw.print(" Max: ");
pw.println((mIndexMax + 5) / 10);
pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType));
@@ -5880,7 +5965,9 @@
final VolumeStreamState streamState = mStreamStates[update.mStreamType];
if (update.hasVolumeIndex()) {
final int index = update.getVolumeIndex();
- streamState.setIndex(index, update.mDevice, update.mCaller);
+ streamState.setIndex(index, update.mDevice, update.mCaller,
+ // trusted as index is always validated before message is posted
+ true /*hasModifyAudioSettings*/);
sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x"
+ Integer.toHexString(update.mDevice) + " volIdx:" + index));
} else {
@@ -6823,7 +6910,8 @@
for (int device : devices) {
int index = streamState.getIndex(device);
if (index > safeMediaVolumeIndex(device)) {
- streamState.setIndex(safeMediaVolumeIndex(device), device, caller);
+ streamState.setIndex(safeMediaVolumeIndex(device), device, caller,
+ true /*hasModifyAudioSettings*/);
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
SENDMSG_QUEUE,
@@ -6857,7 +6945,7 @@
mPendingVolumeCommand.mIndex,
mPendingVolumeCommand.mFlags,
mPendingVolumeCommand.mDevice,
- callingPackage);
+ callingPackage, true /*hasModifyAudioSettings*/);
mPendingVolumeCommand = null;
}
}
@@ -7465,29 +7553,39 @@
@Override
public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid) {
+ String callingPackage, int uid, int pid) {
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
// direction and stream type swap here because the public
// adjustSuggested has a different order than the other methods.
adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage,
- callingPackage, uid);
+ callingPackage, uid, hasModifyAudioSettings);
}
@Override
public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid) {
+ String callingPackage, int uid, int pid) {
if (direction != AudioManager.ADJUST_SAME) {
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
.append(" uid:").append(uid).toString()));
}
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
adjustStreamVolume(streamType, direction, flags, callingPackage,
- callingPackage, uid);
+ callingPackage, uid, hasModifyAudioSettings);
}
@Override
public void setStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid) {
- setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid);
+ String callingPackage, int uid, int pid) {
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid,
+ hasModifyAudioSettings);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index 5d334c2..edc8f15 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -84,11 +84,8 @@
@Override
public void binderDied() {
- super.binderDied();
- // When the binder dies, we should stop the client. This probably belongs in
- // ClientMonitor's binderDied(), but testing all the cases would be tricky.
- // AuthenticationClient is the most user-visible case.
- stop(false /* initiatedByClient */);
+ final boolean clearListener = !isBiometricPrompt();
+ binderDiedInternal(clearListener);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 7e28e94..4ddfe1b 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -113,6 +113,7 @@
private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11;
private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12;
private static final int MSG_ON_SYSTEM_EVENT = 13;
+ private static final int MSG_CLIENT_DIED = 14;
/**
* Authentication either just called and we have not transitioned to the CALLED state, or
@@ -151,8 +152,13 @@
* Device credential in AuthController is showing
*/
static final int STATE_SHOWING_DEVICE_CREDENTIAL = 8;
+ /**
+ * The client binder died, and sensors were authenticating at the time. Cancel has been
+ * requested and we're waiting for the HAL(s) to send ERROR_CANCELED.
+ */
+ static final int STATE_CLIENT_DIED_CANCELLING = 9;
- final class AuthSession {
+ final class AuthSession implements IBinder.DeathRecipient {
// Map of Authenticator/Cookie pairs. We expect to receive the cookies back from
// <Biometric>Services before we can start authenticating. Pairs that have been returned
// are moved to mModalitiesMatched.
@@ -211,7 +217,14 @@
mCallingUserId = callingUserId;
mModality = modality;
mRequireConfirmation = requireConfirmation;
+
Slog.d(TAG, "New AuthSession, mSysUiSessionId: " + mSysUiSessionId);
+
+ try {
+ mClientReceiver.asBinder().linkToDeath(this, 0 /* flags */);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to link to death");
+ }
}
boolean isCrypto() {
@@ -231,6 +244,12 @@
boolean isAllowDeviceCredential() {
return Utils.isCredentialRequested(mBundle);
}
+
+ @Override
+ public void binderDied() {
+ Slog.e(TAG, "Binder died, sysUiSessionId: " + mSysUiSessionId);
+ mHandler.obtainMessage(MSG_CLIENT_DIED).sendToTarget();
+ }
}
private final Injector mInjector;
@@ -370,6 +389,11 @@
break;
}
+ case MSG_CLIENT_DIED: {
+ handleClientDied();
+ break;
+ }
+
default:
Slog.e(TAG, "Unknown message: " + msg);
break;
@@ -1391,6 +1415,7 @@
}
private void handleOnError(int cookie, int modality, int error, int vendorCode) {
+
Slog.d(TAG, "handleOnError: " + error + " cookie: " + cookie);
// Errors can either be from the current auth session or the pending auth session.
// The pending auth session may receive errors such as ERROR_LOCKOUT before
@@ -1431,6 +1456,9 @@
} else if (mCurrentAuthSession.mState == STATE_SHOWING_DEVICE_CREDENTIAL) {
Slog.d(TAG, "Biometric canceled, ignoring from state: "
+ mCurrentAuthSession.mState);
+ } else if (mCurrentAuthSession.mState == STATE_CLIENT_DIED_CANCELLING) {
+ mStatusBarService.hideAuthenticationDialog();
+ mCurrentAuthSession = null;
} else {
Slog.e(TAG, "Impossible session error state: "
+ mCurrentAuthSession.mState);
@@ -1622,6 +1650,36 @@
}
}
+ private void handleClientDied() {
+ if (mCurrentAuthSession == null) {
+ Slog.e(TAG, "Auth session null");
+ return;
+ }
+
+ Slog.e(TAG, "SysUiSessionId: " + mCurrentAuthSession.mSysUiSessionId
+ + " State: " + mCurrentAuthSession.mState);
+
+ try {
+ // Check if any sensors are authenticating. If so, need to cancel them. When
+ // ERROR_CANCELED is received from the HAL, we hide the dialog and cleanup the session.
+ if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
+ mCurrentAuthSession.mState = STATE_CLIENT_DIED_CANCELLING;
+ cancelInternal(mCurrentAuthSession.mToken,
+ mCurrentAuthSession.mOpPackageName,
+ mCurrentAuthSession.mCallingUid,
+ mCurrentAuthSession.mCallingPid,
+ mCurrentAuthSession.mCallingUserId,
+ false /* fromClient */);
+ } else {
+ // If the sensors are not authenticating, set the auth session to null.
+ mStatusBarService.hideAuthenticationDialog();
+ mCurrentAuthSession = null;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception: " + e);
+ }
+ }
+
/**
* Invoked when each service has notified that its client is ready to be started. When
* all biometrics are ready, this invokes the SystemUI dialog through StatusBar.
@@ -1822,11 +1880,11 @@
void cancelInternal(IBinder token, String opPackageName, int callingUid, int callingPid,
int callingUserId, boolean fromClient) {
-
if (mCurrentAuthSession == null) {
Slog.w(TAG, "Skipping cancelInternal");
return;
- } else if (mCurrentAuthSession.mState != STATE_AUTH_STARTED) {
+ } else if (mCurrentAuthSession.mState != STATE_AUTH_STARTED
+ && mCurrentAuthSession.mState != STATE_CLIENT_DIED_CANCELLING) {
Slog.w(TAG, "Skipping cancelInternal, state: " + mCurrentAuthSession.mState);
return;
}
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index 942e050..b029695 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -233,11 +233,17 @@
@Override
public void binderDied() {
+ binderDiedInternal(true /* clearListener */);
+ }
+
+ void binderDiedInternal(boolean clearListener) {
// If the current client dies we should cancel the current operation.
Slog.e(getLogTag(), "Binder died, cancelling client");
stop(false /* initiatedByClient */);
mToken = null;
- mListener = null;
+ if (clearListener) {
+ mListener = null;
+ }
}
@Override
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index d7bd794..c65800a 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -808,14 +808,11 @@
userRecord.mHandler, manager));
for (RouterRecord routerRecord : userRecord.mRouterRecords) {
- // TODO: Do not use notifyPreferredFeaturesChangedToManagers since it updates all
- // managers. Instead, Notify only to the manager that is currently being registered.
-
// TODO: UserRecord <-> routerRecord, why do they reference each other?
// How about removing mUserRecord from routerRecord?
routerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
- routerRecord.mUserRecord.mHandler, routerRecord));
+ obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManager,
+ routerRecord.mUserRecord.mHandler, routerRecord, manager));
}
}
@@ -1928,6 +1925,17 @@
}
}
+ private void notifyPreferredFeaturesChangedToManager(@NonNull RouterRecord routerRecord,
+ @NonNull IMediaRouter2Manager manager) {
+ try {
+ manager.notifyPreferredFeaturesChanged(routerRecord.mPackageName,
+ routerRecord.mDiscoveryPreference.getPreferredFeatures());
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to notify preferred features changed."
+ + " Manager probably died.", ex);
+ }
+ }
+
private void notifyPreferredFeaturesChangedToManagers(@NonNull RouterRecord routerRecord) {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 67f9782..02b7582 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -328,7 +328,7 @@
public void run() {
try {
mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags,
- opPackageName, uid);
+ opPackageName, uid, pid);
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue
+ ", flags=" + flags, e);
@@ -501,12 +501,15 @@
// Must use opPackageName for adjusting volumes with UID.
final String opPackageName;
final int uid;
+ final int pid;
if (asSystemService) {
opPackageName = mContext.getOpPackageName();
uid = Process.SYSTEM_UID;
+ pid = Process.myPid();
} else {
opPackageName = callingOpPackageName;
uid = callingUid;
+ pid = callingPid;
}
mHandler.post(new Runnable() {
@Override
@@ -515,15 +518,15 @@
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream,
- direction, flags, opPackageName, uid);
+ direction, flags, opPackageName, uid, pid);
} else {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
AudioManager.USE_DEFAULT_STREAM_TYPE, direction,
- flags | previousFlagPlaySound, opPackageName, uid);
+ flags | previousFlagPlaySound, opPackageName, uid, pid);
}
} else {
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
- opPackageName, uid);
+ opPackageName, uid, pid);
}
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream="
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 84ec440..e16582f 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -2107,16 +2107,19 @@
public void run() {
final String callingOpPackageName;
final int callingUid;
+ final int callingPid;
if (asSystemService) {
callingOpPackageName = mContext.getOpPackageName();
callingUid = Process.myUid();
+ callingPid = Process.myPid();
} else {
callingOpPackageName = opPackageName;
callingUid = uid;
+ callingPid = pid;
}
try {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream,
- direction, flags, callingOpPackageName, callingUid);
+ direction, flags, callingOpPackageName, callingUid, callingPid);
} catch (SecurityException | IllegalArgumentException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction
+ ", suggestedStream=" + suggestedStream + ", flags=" + flags
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9de34a9..a5b1bf9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -5595,10 +5595,7 @@
userId);
} else if (packageSetting.sharedUser == null && !isUpgradeToR) {
Slog.w(TAG, "Missing permission state for package: " + packageName);
- generateFallbackPermissionsStateLpr(
- packageSetting.pkg.getRequestedPermissions(),
- packageSetting.pkg.getTargetSdkVersion(),
- packageSetting.getPermissionsState(), userId);
+ packageSetting.getPermissionsState().setMissing(true, userId);
}
}
@@ -5616,22 +5613,7 @@
userId);
} else if (!isUpgradeToR) {
Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName);
- ArraySet<String> requestedPermissions = new ArraySet<>();
- int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
- int sharedUserPackagesSize = sharedUserSetting.packages.size();
- for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) {
- PackageSetting packageSetting = sharedUserSetting.packages.valueAt(
- packagesI);
- if (packageSetting == null || packageSetting.pkg == null
- || !packageSetting.getInstalled(userId)) {
- continue;
- }
- AndroidPackage pkg = packageSetting.pkg;
- requestedPermissions.addAll(pkg.getRequestedPermissions());
- targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion());
- }
- generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion,
- sharedUserSetting.getPermissionsState(), userId);
+ sharedUserSetting.getPermissionsState().setMissing(true, userId);
}
}
}
@@ -5663,30 +5645,6 @@
}
}
- private void generateFallbackPermissionsStateLpr(
- @NonNull Collection<String> requestedPermissions, int targetSdkVersion,
- @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
- for (String permissionName : requestedPermissions) {
- BasePermission permission = mPermissions.getPermission(permissionName);
- if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
- && permission.isRuntime() && !permission.isRemoved()) {
- if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) {
- permissionsState.updatePermissionFlags(permission, userId,
- PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
- PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
- }
- if (targetSdkVersion < Build.VERSION_CODES.M) {
- permissionsState.updatePermissionFlags(permission, userId,
- PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
- | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
- PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
- | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
- permissionsState.grantRuntimePermission(permission, userId);
- }
- }
- }
- }
-
@GuardedBy("Settings.this.mLock")
private void readLegacyStateForUserSyncLPr(int userId) {
File permissionsFile = getUserRuntimePermissionsFile(userId);
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 163504c..b0d4d95 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -155,6 +155,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -2478,13 +2479,60 @@
}
final PermissionsState permissionsState = ps.getPermissionsState();
- PermissionsState origPermissions = permissionsState;
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
boolean runtimePermissionsRevoked = false;
int[] updatedUserIds = EMPTY_INT_ARRAY;
+ for (int userId : currentUserIds) {
+ if (permissionsState.isMissing(userId)) {
+ Collection<String> requestedPermissions;
+ int targetSdkVersion;
+ if (!ps.isSharedUser()) {
+ requestedPermissions = pkg.getRequestedPermissions();
+ targetSdkVersion = pkg.getTargetSdkVersion();
+ } else {
+ requestedPermissions = new ArraySet<>();
+ targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ List<AndroidPackage> packages = ps.getSharedUser().getPackages();
+ int packagesSize = packages.size();
+ for (int i = 0; i < packagesSize; i++) {
+ AndroidPackage sharedUserPackage = packages.get(i);
+ requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions());
+ targetSdkVersion = Math.min(targetSdkVersion,
+ sharedUserPackage.getTargetSdkVersion());
+ }
+ }
+
+ for (String permissionName : requestedPermissions) {
+ BasePermission permission = mSettings.getPermission(permissionName);
+ if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
+ && permission.isRuntime() && !permission.isRemoved()) {
+ if (permission.isHardOrSoftRestricted()
+ || permission.isImmutablyRestricted()) {
+ permissionsState.updatePermissionFlags(permission, userId,
+ PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
+ PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
+ }
+ if (targetSdkVersion < Build.VERSION_CODES.M) {
+ permissionsState.updatePermissionFlags(permission, userId,
+ PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+ | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
+ PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+ | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
+ permissionsState.grantRuntimePermission(permission, userId);
+ }
+ }
+ }
+
+ permissionsState.setMissing(false, userId);
+ updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
+ }
+ }
+
+ PermissionsState origPermissions = permissionsState;
+
boolean changedInstallPermission = false;
if (replace) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 11e29a0..bad59cb 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -16,6 +16,8 @@
package com.android.server.pm.permission;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.ArrayMap;
@@ -30,6 +32,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -70,6 +73,9 @@
private int[] mGlobalGids = NO_GIDS;
+ @Nullable
+ private SparseBooleanArray mMissing;
+
private SparseBooleanArray mPermissionReviewRequired;
public PermissionsState() {
@@ -132,6 +138,23 @@
other.mGlobalGids.length);
}
+ if (mMissing != null) {
+ if (other.mMissing == null) {
+ mMissing = null;
+ } else {
+ mMissing.clear();
+ }
+ }
+ if (other.mMissing != null) {
+ if (mMissing == null) {
+ mMissing = new SparseBooleanArray();
+ }
+ final int missingSize = other.mMissing.size();
+ for (int i = 0; i < missingSize; i++) {
+ mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i));
+ }
+ }
+
if (mPermissionReviewRequired != null) {
if (other.mPermissionReviewRequired == null) {
mPermissionReviewRequired = null;
@@ -175,6 +198,10 @@
}
}
+ if (!Objects.equals(mMissing, other.mMissing)) {
+ return false;
+ }
+
if (mPermissionReviewRequired == null) {
if (other.mPermissionReviewRequired != null) {
return false;
@@ -185,6 +212,35 @@
return Arrays.equals(mGlobalGids, other.mGlobalGids);
}
+ /**
+ * Check whether the permissions state is missing for a user. This can happen if permission
+ * state is rolled back and we'll need to generate a reasonable default state to keep the app
+ * usable.
+ */
+ public boolean isMissing(@UserIdInt int userId) {
+ return mMissing != null && mMissing.get(userId);
+ }
+
+ /**
+ * Set whether the permissions state is missing for a user. This can happen if permission state
+ * is rolled back and we'll need to generate a reasonable default state to keep the app usable.
+ */
+ public void setMissing(boolean missing, @UserIdInt int userId) {
+ if (missing) {
+ if (mMissing == null) {
+ mMissing = new SparseBooleanArray();
+ }
+ mMissing.put(userId, true);
+ } else {
+ if (mMissing != null) {
+ mMissing.delete(userId);
+ if (mMissing.size() == 0) {
+ mMissing = null;
+ }
+ }
+ }
+ }
+
public boolean isPermissionReviewRequired(int userId) {
return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId);
}
@@ -569,6 +625,7 @@
invalidateCache();
}
+ mMissing = null;
mPermissionReviewRequired = null;
}
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 39f7ac0..9c3a394 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -339,7 +339,7 @@
});
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
// Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreports
- mDialog.getWindow().setFlags(FLAG_ALT_FOCUSABLE_IM, FLAG_ALT_FOCUSABLE_IM);
+ dialog.getWindow().setFlags(FLAG_ALT_FOCUSABLE_IM, FLAG_ALT_FOCUSABLE_IM);
dialog.setOnDismissListener(this);
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index d6c48a0..cc36935 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -26,7 +26,6 @@
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.storage.StorageManager.PROP_LEGACY_OP_STICKY;
import static java.lang.Integer.min;
@@ -37,13 +36,17 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.storage.StorageManager;
import android.os.storage.StorageManagerInternal;
+import android.provider.DeviceConfig;
import com.android.server.LocalServices;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import java.util.Arrays;
+import java.util.HashSet;
+
/**
* The behavior of soft restricted permissions is different for each permission. This class collects
* the policies in one place.
@@ -65,8 +68,8 @@
}
};
- private static final boolean isLegacyStorageAppOpStickyGlobal = SystemProperties.getBoolean(
- PROP_LEGACY_OP_STICKY, /*defaultValue*/true);
+ private static final HashSet<String> sForcedScopedStorageAppWhitelist = new HashSet<>(
+ Arrays.asList(getForcedScopedStorageAppWhitelist()));
/**
* TargetSDK is per package. To make sure two apps int the same shared UID do not fight over
@@ -141,12 +144,13 @@
shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage()
&& smInternal.hasLegacyExternalStorage(appInfo.uid);
targetSDK = getMinimumTargetSDK(context, appInfo, user);
- // LEGACY_STORAGE op is normally sticky for apps targetig <= Q.
- // However, this device can be configured to make it non-sticky.
- boolean isLegacyAppOpSticky = isLegacyStorageAppOpStickyGlobal
- && targetSDK <= Build.VERSION_CODES.Q;
+
shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
- || (!isLegacyAppOpSticky && !shouldPreserveLegacyExternalStorage);
+ || (targetSDK > Build.VERSION_CODES.Q
+ && !shouldPreserveLegacyExternalStorage)
+ // If the device is configured to force this app into scoped storage,
+ // then we should apply the restriction
+ || sForcedScopedStorageAppWhitelist.contains(appInfo.packageName);
} else {
isWhiteListed = false;
shouldApplyRestriction = false;
@@ -245,6 +249,15 @@
return false;
}
+ private static String[] getForcedScopedStorageAppWhitelist() {
+ final String rawList = DeviceConfig.getString(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+ StorageManager.PROP_FORCED_SCOPED_STORAGE_WHITELIST, /*defaultValue*/"");
+ if (rawList == null || rawList.equals("")) {
+ return new String[0];
+ }
+ return rawList.split(",");
+ }
+
/**
* @return If the permission can be granted
*/
diff --git a/services/core/java/com/android/server/textclassifier/IconsContentProvider.java b/services/core/java/com/android/server/textclassifier/IconsContentProvider.java
index d19a707..9b3176d 100644
--- a/services/core/java/com/android/server/textclassifier/IconsContentProvider.java
+++ b/services/core/java/com/android/server/textclassifier/IconsContentProvider.java
@@ -25,6 +25,7 @@
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
+import android.os.UserHandle;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -51,7 +52,7 @@
try {
final ResourceInfo res = IconsUriHelper.getInstance().getResourceInfo(uri);
final Drawable drawable = Icon.createWithResource(res.packageName, res.id)
- .loadDrawable(getContext());
+ .loadDrawableAsUser(getContext(), UserHandle.getCallingUserId());
final byte[] data = getBitmapData(drawable);
final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
final ParcelFileDescriptor readSide = pipe[0];
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 15b6a8d..72cdf4a 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -114,7 +114,7 @@
private static final String TAG = "UriGrantsManagerService";
// Maximum number of persisted Uri grants a package is allowed
private static final int MAX_PERSISTED_URI_GRANTS = 128;
- private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true;
+ private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
private final Object mLock = new Object();
private final H mH;
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index d8a4ecb..1cd94b4 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1387,9 +1387,7 @@
return false;
}
- /**
- * @return whether the given task can be trimmed even if it is outside the visible range.
- */
+ /** @return whether the given task can be trimmed even if it is outside the visible range. */
protected boolean isTrimmable(Task task) {
final ActivityStack stack = task.getStack();
@@ -1404,9 +1402,13 @@
return false;
}
+ final ActivityStack rootHomeTask = stack.getDisplayArea().getRootHomeTask();
+ // Home stack does not exist. Don't trim the task.
+ if (rootHomeTask == null) {
+ return false;
+ }
// Trim tasks that are behind the home task.
- final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
- return task.compareTo(taskDisplayArea.getRootHomeTask()) < 0;
+ return task.compareTo(rootHomeTask) < 0;
}
/** Remove the tasks that user may not be able to return. */
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index cbc1bdf..f1b322e 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -406,8 +406,9 @@
}
// Save the minimized home height
- mMinimizedHomeBounds = mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask()
- .getBounds();
+ final ActivityStack rootHomeTask =
+ mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask();
+ mMinimizedHomeBounds = rootHomeTask != null ? rootHomeTask.getBounds() : null;
mService.mWindowPlacerLocked.performSurfacePlacement();
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index c02e0a1..c7f7834 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -387,9 +387,11 @@
int getMode() {
final DisplayContent dc = mWindowContainer.getDisplayContent();
final ActivityRecord topActivity = mWindowContainer.getTopMostActivity();
+ // Note that opening/closing transitions are per-activity while changing transitions
+ // are per-task.
if (dc.mOpeningApps.contains(topActivity)) {
return RemoteAnimationTarget.MODE_OPENING;
- } else if (dc.mChangingContainers.contains(topActivity)) {
+ } else if (dc.mChangingContainers.contains(mWindowContainer)) {
return RemoteAnimationTarget.MODE_CHANGING;
} else {
return RemoteAnimationTarget.MODE_CLOSING;
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 6ce36f1..6661c30 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -195,7 +195,7 @@
return mChildren.indexOf(stack);
}
- ActivityStack getRootHomeTask() {
+ @Nullable ActivityStack getRootHomeTask() {
return mRootHomeTask;
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index e2023ae..a1fbb59 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2184,7 +2184,8 @@
final int appStackClipMode = getDisplayContent().mAppTransition.getAppStackClipMode();
// Separate position and size for use in animators.
- mTmpRect.set(getAnimationBounds(appStackClipMode));
+ final Rect screenBounds = getAnimationBounds(appStackClipMode);
+ mTmpRect.set(screenBounds);
getAnimationPosition(mTmpPoint);
if (!sHierarchicalAnimations) {
// Non-hierarchical animation uses position in global coordinates.
@@ -2203,7 +2204,7 @@
localBounds.offsetTo(mTmpPoint.x, mTmpPoint.y);
final RemoteAnimationController.RemoteAnimationRecord adapters =
controller.createRemoteAnimationRecord(this, mTmpPoint, localBounds,
- mTmpRect, (isChanging ? mSurfaceFreezer.mFreezeBounds : null));
+ screenBounds, (isChanging ? mSurfaceFreezer.mFreezeBounds : null));
resultAdapters = new Pair<>(adapters.mAdapter, adapters.mThumbnailAdapter);
} else if (isChanging) {
final float durationScale = mWmService.getTransitionAnimationScaleLocked();
@@ -2616,10 +2617,8 @@
return willSync;
}
- boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
- int waitingId) {
- boolean willSync = true;
-
+ boolean setPendingListener(BLASTSyncEngine.TransactionReadyListener waitingListener,
+ int waitingId) {
// If we are invisible, no need to sync, likewise if we are already engaged in a sync,
// we can't support overlapping syncs on a single container yet.
if (!isVisible() || mWaitingListener != null) {
@@ -2630,6 +2629,15 @@
// Make sure to set these before we call setReady in case the sync was a no-op
mWaitingSyncId = waitingId;
mWaitingListener = waitingListener;
+ return true;
+ }
+
+ boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
+ int waitingId) {
+ boolean willSync = setPendingListener(waitingListener, waitingId);
+ if (!willSync) {
+ return false;
+ }
int localId = mBLASTSyncEngine.startSyncSet(this);
willSync |= addChildrenToSyncSet(localId);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index fe68cd6..20b109b 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1315,12 +1315,15 @@
*
* @param isCached whether or not the process is cached.
*/
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public void onProcCachedStateChanged(boolean isCached) {
- synchronized (mAtm.mGlobalLock) {
- if (!isCached && mPendingConfiguration != null) {
- final Configuration config = mPendingConfiguration;
- mPendingConfiguration = null;
- dispatchConfigurationChange(config);
+ if (!isCached) {
+ synchronized (mAtm.mGlobalLockWithoutBoost) {
+ if (mPendingConfiguration != null) {
+ final Configuration config = mPendingConfiguration;
+ mPendingConfiguration = null;
+ dispatchConfigurationChange(config);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e925ce5..fd18e6f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1509,7 +1509,7 @@
return mActivityRecord != null ? mActivityRecord.getTask() : null;
}
- ActivityStack getRootTask() {
+ @Nullable ActivityStack getRootTask() {
final Task task = getTask();
if (task != null) {
return (ActivityStack) task.getRootTask();
@@ -2527,7 +2527,7 @@
final Task task = getTask();
if (task != null) {
task.getDimBounds(mTmpRect);
- } else {
+ } else if (getRootTask() != null) {
getRootTask().getDimBounds(mTmpRect);
}
}
@@ -5707,16 +5707,20 @@
@Override
boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
int waitingId) {
- if (!isVisible()) {
+ boolean willSync = setPendingListener(waitingListener, waitingId);
+ if (!willSync) {
return false;
}
- mWaitingListener = waitingListener;
- mWaitingSyncId = waitingId;
- mUsingBLASTSyncTransaction = true;
mLocalSyncId = mBLASTSyncEngine.startSyncSet(this);
addChildrenToSyncSet(mLocalSyncId);
+ // In the WindowContainer implementation we immediately mark ready
+ // since a generic WindowContainer only needs to wait for its
+ // children to finish and is immediately ready from its own
+ // perspective but at the WindowState level we need to wait for ourselves
+ // to draw even if the children draw first our don't need to sync, so we omit
+ // the set ready call until later in finishDrawing()
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
mWmService.mH.sendNewMessageDelayed(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this,
BLAST_TIMEOUT_DURATION);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c570cf1..b30d408 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1257,19 +1257,25 @@
mYOffset = dy;
mWallpaperScale = scale;
- try {
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
- mService.openSurfaceTransaction();
- setWallpaperPositionAndScale(dx, dy, scale, false);
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error positioning surface of " + mWin
- + " pos=(" + dx + "," + dy + ")", e);
- } finally {
- mService.closeSurfaceTransaction("setWallpaperOffset");
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION setWallpaperOffset");
- return true;
+ if (mSurfaceController != null) {
+ try {
+ if (SHOW_LIGHT_TRANSACTIONS) {
+ Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
+ }
+ mService.openSurfaceTransaction();
+ setWallpaperPositionAndScale(dx, dy, scale, false);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error positioning surface of " + mWin
+ + " pos=(" + dx + "," + dy + ")", e);
+ } finally {
+ mService.closeSurfaceTransaction("setWallpaperOffset");
+ if (SHOW_LIGHT_TRANSACTIONS) {
+ Slog.i(TAG, "<<< CLOSE TRANSACTION setWallpaperOffset");
+ }
+ }
}
+
+ return true;
}
private void setWallpaperPositionAndScale(int dx, int dy, float scale,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 285caf3..48ec529 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -115,6 +115,8 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ resetReceivers();
+
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getResources()).thenReturn(mResources);
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
@@ -147,6 +149,74 @@
}
@Test
+ public void testClientBinderDied_whenPaused() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
+
+ invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
+ true /* requireConfirmation */, null /* authenticators */);
+ waitForIdle();
+ verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession),
+ anyInt());
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
+ BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
+ 0 /* vendorCode */);
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_AUTH_PAUSED,
+ mBiometricService.mCurrentAuthSession.mState);
+
+ mBiometricService.mCurrentAuthSession.binderDied();
+ waitForIdle();
+
+ assertNull(mBiometricService.mCurrentAuthSession);
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void testClientBinderDied_whenAuthenticating() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
+
+ invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
+ true /* requireConfirmation */, null /* authenticators */);
+ waitForIdle();
+ verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession),
+ anyInt());
+
+ assertEquals(BiometricService.STATE_AUTH_STARTED,
+ mBiometricService.mCurrentAuthSession.mState);
+ mBiometricService.mCurrentAuthSession.binderDied();
+ waitForIdle();
+
+ assertNotNull(mBiometricService.mCurrentAuthSession);
+ verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
+ assertEquals(BiometricService.STATE_CLIENT_DIED_CANCELLING,
+ mBiometricService.mCurrentAuthSession.mState);
+
+ verify(mBiometricService.mAuthenticators.get(0).impl).cancelAuthenticationFromService(
+ any(),
+ any(),
+ anyInt(),
+ anyInt(),
+ anyInt(),
+ eq(false) /* fromClient */);
+
+ // Simulate ERROR_CANCELED received from HAL
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
+ BiometricConstants.BIOMETRIC_ERROR_CANCELED,
+ 0 /* vendorCode */);
+ waitForIdle();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
+ assertNull(mBiometricService.mCurrentAuthSession);
+ }
+
+ @Test
public void testAuthenticate_credentialAllowedButNotSetup_returnsNoDeviceCredential()
throws Exception {
when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(false);
@@ -311,7 +381,7 @@
eq(0 /* vendorCode */));
// Enrolled, not disabled in settings, user requires confirmation in settings
- resetReceiver();
+ resetReceivers();
when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(true);
when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt()))
.thenReturn(true);
@@ -332,7 +402,7 @@
anyInt() /* callingUserId */);
// Enrolled, not disabled in settings, user doesn't require confirmation in settings
- resetReceiver();
+ resetReceivers();
when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt()))
.thenReturn(false);
invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
@@ -1198,7 +1268,7 @@
eq(0) /* vendorCode */);
// Request for weak auth works
- resetReceiver();
+ resetReceivers();
authenticators = Authenticators.BIOMETRIC_WEAK;
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
invokeCanAuthenticate(mBiometricService, authenticators));
@@ -1217,7 +1287,7 @@
anyInt() /* sysUiSessionId */);
// Requesting strong and credential, when credential is setup
- resetReceiver();
+ resetReceivers();
authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(true);
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
@@ -1244,7 +1314,7 @@
}
}
- resetReceiver();
+ resetReceivers();
authenticators = Authenticators.BIOMETRIC_STRONG;
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
invokeCanAuthenticate(mBiometricService, authenticators));
@@ -1449,9 +1519,12 @@
}
}
- private void resetReceiver() {
+ private void resetReceivers() {
mReceiver1 = mock(IBiometricServiceReceiver.class);
mReceiver2 = mock(IBiometricServiceReceiver.class);
+
+ when(mReceiver1.asBinder()).thenReturn(mock(Binder.class));
+ when(mReceiver2.asBinder()).thenReturn(mock(Binder.class));
}
private void resetStatusBar() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index fdc5c7b..71dabc5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -758,6 +758,28 @@
}
@Test
+ public void testBLASTCallbackNoDoubleAdd() {
+ final ActivityStack stackController1 = createStack();
+ final Task task = createTask(stackController1);
+ final ITaskOrganizer organizer = registerMockOrganizer();
+ final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
+ makeWindowVisible(w);
+
+ BLASTSyncEngine bse = new BLASTSyncEngine();
+
+ BLASTSyncEngine.TransactionReadyListener transactionListener =
+ mock(BLASTSyncEngine.TransactionReadyListener.class);
+
+ int id = bse.startSyncSet(transactionListener);
+ assertTrue(bse.addToSyncSet(id, w));
+ assertFalse(bse.addToSyncSet(id, w));
+
+ // Clean-up
+ bse.setReady(id);
+ }
+
+
+ @Test
public void testBLASTCallbackWithInvisibleWindow() {
final ActivityStack stackController1 = createStack();
final Task task = createTask(stackController1);