Merge "Fix NPE in InlineContentView" into rvc-dev
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2216633..052358b 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -450,13 +450,28 @@
TvCasSessionOpenStatus tv_cas_session_open_status =
280 [(module) = "framework"];
AssistantInvocationReported assistant_invocation_reported = 281 [(module) = "framework"];
+ DisplayWakeReported display_wake_reported = 282 [(module) = "framework"];
+ CarUserHalModifyUserRequestReported car_user_hal_modify_user_request_reported =
+ 283 [(module) = "car"];
+ CarUserHalModifyUserResponseReported car_user_hal_modify_user_response_reported =
+ 284 [(module) = "car"];
+ CarUserHalPostSwitchResponseReported car_user_hal_post_switch_response_reported =
+ 285 [(module) = "car"];
+ CarUserHalInitialUserInfoRequestReported car_user_hal_initial_user_info_request_reported =
+ 286 [(module) = "car"];
+ CarUserHalInitialUserInfoResponseReported car_user_hal_initial_user_info_response_reported =
+ 287 [(module) = "car"];
+ CarUserHalUserAssociationRequestReported car_user_hal_user_association_request_reported =
+ 288 [(module) = "car"];
+ CarUserHalSetUserAssociationResponseReported car_user_hal_set_user_association_response_reported =
+ 289 [(module) = "car"];
// StatsdStats tracks platform atoms with ids upto 500.
// Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
}
// Pulled events will start at field 10000.
- // Next: 10084
+ // Next: 10081
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
@@ -547,7 +562,7 @@
SimSlotState sim_slot_state = 10078 [(module) = "telephony"];
SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
SettingSnapshot setting_snapshot = 10080 [(module) = "framework"];
- DisplayWakeReason display_wake_reason = 10081 [(module) = "framework"];
+ //10081 free for use
DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"];
BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered =
10083 [(module) = "framework"];
@@ -8001,6 +8016,245 @@
}
/**
+ * Logs when Car User Hal is requested to switch/create/remove user.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalModifyUserRequestReported {
+ // Request id for the request.
+ optional int32 request_id = 1;
+ // Request type.
+ enum RequestType {
+ UNKNOWN = 0;
+ // Car user manager requested user switch.
+ SWITCH_REQUEST_ANDROID = 1;
+ // OEM requested User switch.
+ SWITCH_REQUEST_OEM = 2;
+ // Hal switch requested after android switch using activity manager.
+ SWITCH_REQUEST_LEGACY = 3;
+ // Create User
+ CREATE_REQUEST = 4;
+ // Remove User
+ REMOVE_REQUEST = 5;
+ }
+ optional RequestType request_type = 2;
+ // Android User id of the current user which can only be 0, 10, 11 and so on.
+ // -1 if not available.
+ optional int32 user_id = 3;
+ // VHAL flags of the current user. (-1 if not available)
+ optional int32 user_flags = 4;
+ // Android User id of the target user for switch/create/remove. It can only
+ // be 0, 10, 11 and so on. -1 if not available.
+ optional int32 target_user_id = 5;
+ // VHAL flags of the target user for switch/create/remove. (-1 if not available)
+ optional int32 target_user_flags = 6;
+ // Request timeout Milliseconds (-1 if not available)
+ optional int32 timeout_millis = 7;
+}
+
+/**
+ * Logs when Car User Hal responds to switch/create user request.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalModifyUserResponseReported {
+ // Request id of the request associated with the response.
+ optional int32 request_id = 1;
+ // Car user hal callback status.
+ enum CallbackStatus {
+ UNKNOWN = 0;
+ // Hal response was invalid.
+ INVALID = 1;
+ // Hal response was ok.
+ OK = 2;
+ // Hal timeout during set call.
+ HAL_SET_TIMEOUT = 3;
+ // Hal response timeout.
+ HAL_RESPONSE_TIMEOUT = 4;
+ // Hal responded with wrong info.
+ WRONG_HAL_RESPONSE = 5;
+ // Hal is processing multiple requests simultaneously.
+ CONCURRENT_OPERATION = 6;
+ }
+ optional CallbackStatus callback_status = 2;
+
+ // Hal request status for user switch/create/remove.
+ enum HalRequestStatus {
+ UNSPECIFIED = 0;
+ // Hal request for user switch/create is successful.
+ SUCCESS = 1;
+ // Hal request for user switch/create failed.
+ FAILURE = 2;
+ }
+ optional HalRequestStatus request_status = 3;
+}
+
+/**
+ * Logs when post switch response is posted to Car User Hal.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalPostSwitchResponseReported {
+ // Request id.
+ optional int32 request_id = 1;
+
+ // Android user switch status.
+ enum UserSwitchStatus {
+ UNKNOWN = 0;
+ // Android user switch is successful.
+ SUCCESS = 1;
+ // Android user switch failed.
+ FAILURE = 2;
+ }
+ optional UserSwitchStatus switch_status = 2;
+}
+
+/**
+ * Logs when initial user information is requested from Car User Hal.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalInitialUserInfoRequestReported {
+ // Request id for the request.
+ optional int32 request_id = 1;
+
+ // Request type for initial user information.
+ enum InitialUserInfoRequestType {
+ UNKNOWN = 0;
+ // At the first time Android was booted (or after a factory reset).
+ FIRST_BOOT = 1;
+ // At the first time Android was booted after the system was updated.
+ FIRST_BOOT_AFTER_OTA = 2;
+ // When Android was booted "from scratch".
+ COLD_BOOT = 3;
+ // When Android was resumed after the system was suspended to memory.
+ RESUME = 4;
+ }
+ optional InitialUserInfoRequestType request_type = 2;
+ // Request timeout Milliseconds (-1 if not available)
+ optional int32 timeout_millis = 3;
+}
+
+/**
+ * Logs when Car User Hal responds to initial user information requests.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalInitialUserInfoResponseReported {
+ // Request id of the request associated with the response.
+ optional int32 request_id = 1;
+ // Car user hal callback status.
+ enum CallbackStatus {
+ UNKNOWN = 0;
+ // Hal response was invalid.
+ INVALID = 1;
+ // Hal response was ok.
+ OK = 2;
+ // Hal timeout during set call.
+ HAL_SET_TIMEOUT = 3;
+ // Hal response timeout.
+ HAL_RESPONSE_TIMEOUT = 4;
+ // Hal responded with wrong info.
+ WRONG_HAL_RESPONSE = 5;
+ // Hal is processing multiple requests simultaneously.
+ CONCURRENT_OPERATION = 6;
+ }
+ optional CallbackStatus callback_status = 2;
+ // Response for initial user information request.
+ enum InitialUserInfoResponseAction {
+ UNSPECIFIED = 0;
+ // Let the Android System decide what to do.
+ DEFAULT = 1;
+ // Switch to an existing Android user.
+ SWITCH = 2;
+ // Create a new Android user (and switch to it).
+ CREATE = 3;
+ }
+ optional InitialUserInfoResponseAction response_action = 3;
+ // Android User id of the target user which can only be 0, 10, 11 and so on.
+ // -1 if not available.
+ optional int32 target_user = 4;
+ // VHAL flags of the current user. (-1 if not available)
+ optional int32 target_user_flags = 5;
+ // User locales
+ optional string user_locales = 6;
+}
+
+/**
+ * Logs when set user association is requested from Car User Hal.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalUserAssociationRequestReported {
+ // Request id for the request.
+ optional int32 request_id = 1;
+ // Request type.
+ enum RequestType {
+ UNKNOWN = 0;
+ // For setting user association information.
+ SET = 1;
+ // For getting user association information.
+ GET = 2;
+ }
+ optional RequestType request_type = 2;
+ // Android User id of the current user which can only be 0, 10, 11 and so on.
+ // -1 if not available.
+ optional int32 current_user_id = 3;
+ // VHAL flags of the current user. (-1 if not available)
+ optional int32 current_user_flags = 4;
+ // Number of the set associations requested.
+ optional int32 number_associations = 5;
+ // Concatenated string for the types from set associations request.
+ // This is a string converted from an array of integers.
+ optional string user_identification_association_types = 6;
+ // Concatenated string for the values from set associations request.
+ // This is a string converted from an array of integers.
+ optional string user_identification_association_values = 7;
+}
+
+/**
+ * Logs when Car User Hal responds to set user association requests.
+ *
+ * Logged from:
+ * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
+ */
+message CarUserHalSetUserAssociationResponseReported {
+ // Request id of the request associated with the response.
+ optional int32 request_id = 1;
+ // Car user hal callback status.
+ enum CallbackStatus {
+ UNKNOWN = 0;
+ // Hal response was invalid.
+ INVALID = 1;
+ // Hal response was ok.
+ OK = 2;
+ // Hal timeout during set call.
+ HAL_SET_TIMEOUT = 3;
+ // Hal response timeout.
+ HAL_RESPONSE_TIMEOUT = 4;
+ // Hal responded with wrong info.
+ WRONG_HAL_RESPONSE = 5;
+ // Hal is processing multiple requests simultaneously.
+ CONCURRENT_OPERATION = 6;
+ }
+ optional CallbackStatus callback_status = 2;
+ // Number of the set associations in the response.
+ optional int32 number_associations = 3;
+ // Concatenated string for the types from set associations request.
+ // This is a string converted from an array of integers.
+ optional string user_identification_association_types = 4;
+ // Concatenated string for the values from set associations request.
+ // This is a string converted from an array of integers.
+ optional string user_identification_association_values = 5;
+}
+
+/**
* Logs whether GarageMode is entered.
*
* Logged from:
@@ -9817,15 +10071,20 @@
optional android.stats.accessibility.ServiceStatus service_status = 2;
}
-message DisplayWakeReason {
+/**
+ * Logs when display wake up.
+ *
+ * Logged from:
+ * services/core/java/com/android/server/power/Notifier.java
+ */
+
+message DisplayWakeReported {
// Wake_up_reason code
// If LOWORD(wake_up_reason) = 0
// reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX
// else reference wake_up_reason to
- // frameworks/base/services/core/java/com/android/server/power/Notifier.java#DispWakeupReason
+ // services/core/java/com/android/server/power/Notifier.java#onWakeUp
optional int32 wake_up_reason = 1;
- // Count of wake up by reason
- optional int32 wake_times = 2;
}
/**
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 635ed13..d650bbc 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -102,6 +102,14 @@
public ActivityView(
@NonNull Context context, @NonNull AttributeSet attrs, int defStyle,
boolean singleTaskInstance, boolean usePublicVirtualDisplay) {
+ this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, false);
+ }
+
+ /** @hide */
+ public ActivityView(
+ @NonNull Context context, @NonNull AttributeSet attrs, int defStyle,
+ boolean singleTaskInstance, boolean usePublicVirtualDisplay,
+ boolean disableSurfaceViewBackgroundLayer) {
super(context, attrs, defStyle);
if (useTaskOrganizer()) {
mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this);
@@ -109,7 +117,7 @@
mTaskEmbedder = new VirtualDisplayTaskEmbedder(context, this, singleTaskInstance,
usePublicVirtualDisplay);
}
- mSurfaceView = new SurfaceView(context);
+ mSurfaceView = new SurfaceView(context, null, 0, 0, disableSurfaceViewBackgroundLayer);
// Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
// as master to synchronize surface view's alpha value.
mSurfaceView.setAlpha(super.getAlpha());
diff --git a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java
index bea1bd6..b3f9e31 100644
--- a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java
+++ b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java
@@ -95,7 +95,7 @@
try {
mService.provideContextBitmap(mUser, bitmap, imageContextRequestExtras);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -117,7 +117,7 @@
try {
mService.provideContextImage(mUser, taskId, imageContextRequestExtras);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -146,7 +146,7 @@
mService.suggestContentSelections(
mUser, request, new SelectionsCallbackWrapper(callback, callbackExecutor));
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -173,7 +173,7 @@
mService.classifyContentSelections(
mUser, request, new ClassificationsCallbackWrapper(callback, callbackExecutor));
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -193,7 +193,7 @@
try {
mService.notifyInteraction(mUser, requestId, interaction);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -213,9 +213,10 @@
mService.isEnabled(mUser, receiver);
return receiver.getIntResult() != 0;
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get the enable status.");
}
- return false;
}
/**
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 6d49add..23c8602 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1072,7 +1072,7 @@
* @param lastFrameNumber last frame number returned from binder.
* @param repeatingRequestTypes the repeating requests' types.
*/
- private void checkEarlyTriggerSequenceComplete(
+ private void checkEarlyTriggerSequenceCompleteLocked(
final int requestId, final long lastFrameNumber,
final int[] repeatingRequestTypes) {
// lastFrameNumber being equal to NO_FRAMES_CAPTURED means that the request
@@ -1212,7 +1212,7 @@
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId,
requestInfo.getLastFrameNumber(),
mRepeatingRequestTypes);
}
@@ -1269,7 +1269,7 @@
return;
}
- checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber, requestTypes);
+ checkEarlyTriggerSequenceCompleteLocked(requestId, lastFrameNumber, requestTypes);
}
}
}
@@ -1302,7 +1302,7 @@
long lastFrameNumber = mRemoteDevice.flush();
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId, lastFrameNumber,
mRepeatingRequestTypes);
mRepeatingRequestId = REQUEST_ID_NONE;
mRepeatingRequestTypes = null;
@@ -1442,78 +1442,135 @@
long completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
long completedReprocessFrameNumber = mFrameNumberTracker.getCompletedReprocessFrameNumber();
long completedZslStillFrameNumber = mFrameNumberTracker.getCompletedZslStillFrameNumber();
- boolean isReprocess = false;
+
Iterator<RequestLastFrameNumbersHolder> iter = mRequestLastFrameNumbersList.iterator();
while (iter.hasNext()) {
final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
- boolean sequenceCompleted = false;
final int requestId = requestLastFrameNumbers.getRequestId();
final CaptureCallbackHolder holder;
- synchronized(mInterfaceLock) {
- if (mRemoteDevice == null) {
- Log.w(TAG, "Camera closed while checking sequences");
- return;
+ if (mRemoteDevice == null) {
+ Log.w(TAG, "Camera closed while checking sequences");
+ return;
+ }
+ if (!requestLastFrameNumbers.isSequenceCompleted()) {
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+ if (lastRegularFrameNumber <= completedFrameNumber
+ && lastReprocessFrameNumber <= completedReprocessFrameNumber
+ && lastZslStillFrameNumber <= completedZslStillFrameNumber) {
+ Log.v(TAG, String.format(
+ "Mark requestId %d as completed, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, completedFrameNumber,
+ lastReprocessFrameNumber, completedReprocessFrameNumber,
+ lastZslStillFrameNumber, completedZslStillFrameNumber));
+ requestLastFrameNumbers.markSequenceCompleted();
}
+ // Call onCaptureSequenceCompleted
int index = mCaptureCallbackMap.indexOfKey(requestId);
holder = (index >= 0) ?
mCaptureCallbackMap.valueAt(index) : null;
- if (holder != null) {
- long lastRegularFrameNumber =
- requestLastFrameNumbers.getLastRegularFrameNumber();
- long lastReprocessFrameNumber =
- requestLastFrameNumbers.getLastReprocessFrameNumber();
- long lastZslStillFrameNumber =
- requestLastFrameNumbers.getLastZslStillFrameNumber();
- // check if it's okay to remove request from mCaptureCallbackMap
- if (lastRegularFrameNumber <= completedFrameNumber
- && lastReprocessFrameNumber <= completedReprocessFrameNumber
- && lastZslStillFrameNumber <= completedZslStillFrameNumber) {
- sequenceCompleted = true;
- mCaptureCallbackMap.removeAt(index);
- if (DEBUG) {
- Log.v(TAG, String.format(
- "Remove holder for requestId %d, because lastRegularFrame %d "
- + "is <= %d, lastReprocessFrame %d is <= %d, "
- + "lastZslStillFrame %d is <= %d", requestId,
- lastRegularFrameNumber, completedFrameNumber,
- lastReprocessFrameNumber, completedReprocessFrameNumber,
- lastZslStillFrameNumber, completedZslStillFrameNumber));
+ if (holder != null && requestLastFrameNumbers.isSequenceCompleted()) {
+ Runnable resultDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!CameraDeviceImpl.this.isClosed()){
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "fire sequence complete for request %d",
+ requestId));
+ }
+
+ holder.getCallback().onCaptureSequenceCompleted(
+ CameraDeviceImpl.this,
+ requestId,
+ requestLastFrameNumbers.getLastFrameNumber());
+ }
}
+ };
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ holder.getExecutor().execute(resultDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
}
- // If no callback is registered for this requestId or sequence completed, remove it
- // from the frame number->request pair because it's not needed anymore.
- if (holder == null || sequenceCompleted) {
+ if (requestLastFrameNumbers.isSequenceCompleted() &&
+ requestLastFrameNumbers.isInflightCompleted()) {
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ if (index >= 0) {
+ mCaptureCallbackMap.removeAt(index);
+ }
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d", requestId));
+ }
iter.remove();
}
+ }
+ }
- // Call onCaptureSequenceCompleted
- if (sequenceCompleted) {
- Runnable resultDispatch = new Runnable() {
- @Override
- public void run() {
- if (!CameraDeviceImpl.this.isClosed()){
- if (DEBUG) {
- Log.d(TAG, String.format(
- "fire sequence complete for request %d",
- requestId));
- }
+ private void removeCompletedCallbackHolderLocked(long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber, long lastCompletedZslStillFrameNumber) {
+ if (DEBUG) {
+ Log.v(TAG, String.format("remove completed callback holders for "
+ + "lastCompletedRegularFrameNumber %d, "
+ + "lastCompletedReprocessFrameNumber %d, "
+ + "lastCompletedZslStillFrameNumber %d",
+ lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber,
+ lastCompletedZslStillFrameNumber));
+ }
- holder.getCallback().onCaptureSequenceCompleted(
- CameraDeviceImpl.this,
- requestId,
- requestLastFrameNumbers.getLastFrameNumber());
- }
+ Iterator<RequestLastFrameNumbersHolder> iter = mRequestLastFrameNumbersList.iterator();
+ while (iter.hasNext()) {
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
+ final int requestId = requestLastFrameNumbers.getRequestId();
+ final CaptureCallbackHolder holder;
+ if (mRemoteDevice == null) {
+ Log.w(TAG, "Camera closed while removing completed callback holders");
+ return;
+ }
+
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+
+ if (lastRegularFrameNumber <= lastCompletedRegularFrameNumber
+ && lastReprocessFrameNumber <= lastCompletedReprocessFrameNumber
+ && lastZslStillFrameNumber <= lastCompletedZslStillFrameNumber) {
+
+ if (requestLastFrameNumbers.isSequenceCompleted()) {
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ if (index >= 0) {
+ mCaptureCallbackMap.removeAt(index);
}
- };
- final long ident = Binder.clearCallingIdentity();
- try {
- holder.getExecutor().execute(resultDispatch);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, lastCompletedRegularFrameNumber,
+ lastReprocessFrameNumber, lastCompletedReprocessFrameNumber,
+ lastZslStillFrameNumber, lastCompletedZslStillFrameNumber));
+ }
+ iter.remove();
+ } else {
+ if (DEBUG) {
+ Log.v(TAG, "Sequence not yet completed for request id " + requestId);
+ }
+ requestLastFrameNumbers.markInflightCompleted();
}
}
}
@@ -1702,6 +1759,12 @@
return;
}
+ // Remove all capture callbacks now that device has gone to IDLE state.
+ removeCompletedCallbackHolderLocked(
+ Long.MAX_VALUE, /*lastCompletedRegularFrameNumber*/
+ Long.MAX_VALUE, /*lastCompletedReprocessFrameNumber*/
+ Long.MAX_VALUE /*lastCompletedZslStillFrameNumber*/);
+
if (!CameraDeviceImpl.this.mIdle) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -1747,7 +1810,7 @@
return;
}
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId, lastFrameNumber,
mRepeatingRequestTypes);
// Check if there is already a new repeating request
if (mRepeatingRequestId == repeatingRequestId) {
@@ -1766,9 +1829,18 @@
public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
int requestId = resultExtras.getRequestId();
final long frameNumber = resultExtras.getFrameNumber();
+ final long lastCompletedRegularFrameNumber =
+ resultExtras.getLastCompletedRegularFrameNumber();
+ final long lastCompletedReprocessFrameNumber =
+ resultExtras.getLastCompletedReprocessFrameNumber();
+ final long lastCompletedZslFrameNumber =
+ resultExtras.getLastCompletedZslFrameNumber();
if (DEBUG) {
- Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber);
+ Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber
+ + ": completedRegularFrameNumber " + lastCompletedRegularFrameNumber
+ + ", completedReprocessFrameNUmber " + lastCompletedReprocessFrameNumber
+ + ", completedZslFrameNumber " + lastCompletedZslFrameNumber);
}
final CaptureCallbackHolder holder;
@@ -1784,6 +1856,12 @@
return;
}
+ // Check if it's okay to remove completed callbacks from mCaptureCallbackMap.
+ // A callback is completed if the corresponding inflight request has been removed
+ // from the inflight queue in cameraservice.
+ removeCompletedCallbackHolderLocked(lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber, lastCompletedZslFrameNumber);
+
// Get the callback for this frame ID, if there is one
holder = CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
diff --git a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
index 1d9d644..413caf5 100644
--- a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
@@ -182,6 +182,12 @@
return;
}
+ // Remove all capture callbacks now that device has gone to IDLE state.
+ removeCompletedCallbackHolderLocked(
+ Long.MAX_VALUE, /*lastCompletedRegularFrameNumber*/
+ Long.MAX_VALUE, /*lastCompletedReprocessFrameNumber*/
+ Long.MAX_VALUE /*lastCompletedZslStillFrameNumber*/);
+
Runnable idleDispatch = new Runnable() {
@Override
public void run() {
@@ -204,10 +210,22 @@
public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
int requestId = resultExtras.getRequestId();
final long frameNumber = resultExtras.getFrameNumber();
+ final long lastCompletedRegularFrameNumber =
+ resultExtras.getLastCompletedRegularFrameNumber();
+ final long lastCompletedReprocessFrameNumber =
+ resultExtras.getLastCompletedReprocessFrameNumber();
+ final long lastCompletedZslFrameNumber =
+ resultExtras.getLastCompletedZslFrameNumber();
final CaptureCallbackHolder holder;
synchronized(mInterfaceLock) {
+ // Check if it's okay to remove completed callbacks from mCaptureCallbackMap.
+ // A callback is completed if the corresponding inflight request has been removed
+ // from the inflight queue in cameraservice.
+ removeCompletedCallbackHolderLocked(lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber, lastCompletedZslFrameNumber);
+
// Get the callback for this frame ID, if there is one
holder = CameraOfflineSessionImpl.this.mCaptureCallbackMap.get(requestId);
@@ -601,6 +619,61 @@
}
}
+ private void removeCompletedCallbackHolderLocked(long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber, long lastCompletedZslStillFrameNumber) {
+ if (DEBUG) {
+ Log.v(TAG, String.format("remove completed callback holders for "
+ + "lastCompletedRegularFrameNumber %d, "
+ + "lastCompletedReprocessFrameNumber %d, "
+ + "lastCompletedZslStillFrameNumber %d",
+ lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber,
+ lastCompletedZslStillFrameNumber));
+ }
+
+ boolean isReprocess = false;
+ Iterator<RequestLastFrameNumbersHolder> iter =
+ mOfflineRequestLastFrameNumbersList.iterator();
+ while (iter.hasNext()) {
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
+ final int requestId = requestLastFrameNumbers.getRequestId();
+ final CaptureCallbackHolder holder;
+
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ holder = (index >= 0) ?
+ mCaptureCallbackMap.valueAt(index) : null;
+ if (holder != null) {
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+ if (lastRegularFrameNumber <= lastCompletedRegularFrameNumber
+ && lastReprocessFrameNumber <= lastCompletedReprocessFrameNumber
+ && lastZslStillFrameNumber <= lastCompletedZslStillFrameNumber) {
+ if (requestLastFrameNumbers.isSequenceCompleted()) {
+ mCaptureCallbackMap.removeAt(index);
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, lastCompletedRegularFrameNumber,
+ lastReprocessFrameNumber, lastCompletedReprocessFrameNumber,
+ lastZslStillFrameNumber, lastCompletedZslStillFrameNumber));
+ }
+
+ iter.remove();
+ } else {
+ Log.e(TAG, "Sequence not yet completed for request id " + requestId);
+ continue;
+ }
+ }
+ }
+ }
+ }
+
public void notifyFailedSwitch() {
synchronized(mInterfaceLock) {
Runnable switchFailDispatch = new Runnable() {
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
index 1ff5bd5..5d9da73 100644
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
@@ -30,6 +30,9 @@
private int partialResultCount;
private int errorStreamId;
private String errorPhysicalCameraId;
+ private long lastCompletedRegularFrameNumber;
+ private long lastCompletedReprocessFrameNumber;
+ private long lastCompletedZslFrameNumber;
public static final @android.annotation.NonNull Parcelable.Creator<CaptureResultExtras> CREATOR =
new Parcelable.Creator<CaptureResultExtras>() {
@@ -51,7 +54,9 @@
public CaptureResultExtras(int requestId, int subsequenceId, int afTriggerId,
int precaptureTriggerId, long frameNumber,
int partialResultCount, int errorStreamId,
- String errorPhysicalCameraId) {
+ String errorPhysicalCameraId, long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber,
+ long lastCompletedZslFrameNumber) {
this.requestId = requestId;
this.subsequenceId = subsequenceId;
this.afTriggerId = afTriggerId;
@@ -60,6 +65,9 @@
this.partialResultCount = partialResultCount;
this.errorStreamId = errorStreamId;
this.errorPhysicalCameraId = errorPhysicalCameraId;
+ this.lastCompletedRegularFrameNumber = lastCompletedRegularFrameNumber;
+ this.lastCompletedReprocessFrameNumber = lastCompletedReprocessFrameNumber;
+ this.lastCompletedZslFrameNumber = lastCompletedZslFrameNumber;
}
@Override
@@ -82,6 +90,9 @@
} else {
dest.writeBoolean(false);
}
+ dest.writeLong(lastCompletedRegularFrameNumber);
+ dest.writeLong(lastCompletedReprocessFrameNumber);
+ dest.writeLong(lastCompletedZslFrameNumber);
}
public void readFromParcel(Parcel in) {
@@ -96,6 +107,9 @@
if (errorPhysicalCameraIdPresent) {
errorPhysicalCameraId = in.readString();
}
+ lastCompletedRegularFrameNumber = in.readLong();
+ lastCompletedReprocessFrameNumber = in.readLong();
+ lastCompletedZslFrameNumber = in.readLong();
}
public String getErrorPhysicalCameraId() {
@@ -129,4 +143,16 @@
public int getErrorStreamId() {
return errorStreamId;
}
+
+ public long getLastCompletedRegularFrameNumber() {
+ return lastCompletedRegularFrameNumber;
+ }
+
+ public long getLastCompletedReprocessFrameNumber() {
+ return lastCompletedReprocessFrameNumber;
+ }
+
+ public long getLastCompletedZslFrameNumber() {
+ return lastCompletedZslFrameNumber;
+ }
}
diff --git a/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
index bd1df9e..0ee4ebc 100644
--- a/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
+++ b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
@@ -38,6 +38,10 @@
// The last ZSL still capture frame number for this request ID. It's
// CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no zsl request.
private final long mLastZslStillFrameNumber;
+ // Whether the sequence is completed. (only consider capture result)
+ private boolean mSequenceCompleted;
+ // Whether the inflight request is completed. (consider result, buffers, and notifies)
+ private boolean mInflightCompleted;
/**
* Create a request-last-frame-numbers holder with a list of requests, request ID, and
@@ -89,6 +93,8 @@
mLastReprocessFrameNumber = lastReprocessFrameNumber;
mLastZslStillFrameNumber = lastZslStillFrameNumber;
mRequestId = requestInfo.getRequestId();
+ mSequenceCompleted = false;
+ mInflightCompleted = false;
}
/**
@@ -137,6 +143,8 @@
mLastZslStillFrameNumber = lastZslStillFrameNumber;
mLastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
mRequestId = requestId;
+ mSequenceCompleted = false;
+ mInflightCompleted = false;
}
/**
@@ -177,5 +185,34 @@
public int getRequestId() {
return mRequestId;
}
+
+ /**
+ * Return whether the capture sequence is completed.
+ */
+ public boolean isSequenceCompleted() {
+ return mSequenceCompleted;
+ }
+
+ /**
+ * Mark the capture sequence as completed.
+ */
+ public void markSequenceCompleted() {
+ mSequenceCompleted = true;
+ }
+
+ /**
+ * Return whether the inflight capture is completed.
+ */
+ public boolean isInflightCompleted() {
+ return mInflightCompleted;
+ }
+
+ /**
+ * Mark the inflight capture as completed.
+ */
+ public void markInflightCompleted() {
+ mInflightCompleted = true;
+ }
+
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index fbc9ac32..fdd578c 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -109,11 +109,12 @@
}
if (holder == null) {
return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
- ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null);
+ ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null,
+ ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE);
}
return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(),
/*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(),
- /*partialResultCount*/1, errorStreamId, null);
+ /*partialResultCount*/1, errorStreamId, null, holder.getFrameNumber(), -1, -1);
}
/**
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index a6bd74a..473e6c5 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -468,8 +468,8 @@
}
/**
- * Returns true iff. the capabilities requested in this NetworkRequest are satisfied by the
- * provided {@link NetworkCapabilities}.
+ * Returns true if and only if the capabilities requested in this NetworkRequest are satisfied
+ * by the provided {@link NetworkCapabilities}.
*
* @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not
* satisfy any request.
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index a4c99c0..39038f5 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -1318,15 +1318,15 @@
Process.ProcessStartResult result;
try {
- // As app zygote is for generating isolated process, at the end it can't access
- // apps data, so doesn't need to its data info.
+ // We will bind mount app data dirs so app zygote can't access /data/data, while
+ // we don't need to bind mount storage dirs as /storage won't be mounted.
result = startViaZygote(processClass, niceName, uid, gid,
gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
true /* startChildZygote */, null /* packageName */,
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
- null /* whitelistedDataInfoMap */, false /* bindMountAppsData*/,
+ null /* whitelistedDataInfoMap */, true /* bindMountAppsData*/,
/* bindMountAppStorageDirs */ false, extraArgs);
} catch (ZygoteStartFailedEx ex) {
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 9b293eb..ef21900 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -157,8 +157,8 @@
* Listen for changes to the device's cell location. Note that
* this will result in frequent callbacks to the listener.
* {@more}
- * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
- * ACCESS_COARSE_LOCATION}
+ * Requires Permission: {@link android.Manifest.permission#ACCESS_FINE_LOCATION
+ * ACCESS_FINE_LOCATION}
* <p>
* If you need regular location updates but want more control over
* the update interval or location precision, you can set up a listener
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 3869484..ae70a49 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -22,6 +22,8 @@
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.toPublicType;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
@@ -271,10 +273,13 @@
// no-op for types that always return ShowResult#SHOW_IMMEDIATELY.
}
- void updateSource(InsetsSource newSource) {
+ @VisibleForTesting(visibility = PACKAGE)
+ public void updateSource(InsetsSource newSource) {
InsetsSource source = mState.peekSource(mType);
if (source == null || mController.getAnimationType(mType) == ANIMATION_TYPE_NONE
|| source.getFrame().equals(newSource.getFrame())) {
+ mPendingFrame = null;
+ mPendingVisibleFrame = null;
mState.addSource(newSource);
return;
}
@@ -292,7 +297,8 @@
if (DEBUG) Log.d(TAG, "updateSource: " + newSource);
}
- boolean notifyAnimationFinished() {
+ @VisibleForTesting(visibility = PACKAGE)
+ public boolean notifyAnimationFinished() {
if (mPendingFrame != null) {
InsetsSource source = mState.getSource(mType);
source.setFrame(mPendingFrame);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index a954f36..57f91ed 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -134,6 +134,7 @@
// we need to preserve the old one until the new one has drawn.
SurfaceControl mDeferredDestroySurfaceControl;
SurfaceControl mBackgroundControl;
+ private boolean mDisableBackgroundLayer = false;
/**
* We use this lock in SOME cases when reading or writing SurfaceControl,
@@ -245,10 +246,17 @@
}
public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ this(context, attrs, defStyleAttr, defStyleRes, false);
+ }
+
+ /** @hide */
+ public SurfaceView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes, boolean disableBackgroundLayer) {
super(context, attrs, defStyleAttr, defStyleRes);
mRenderNode.addPositionUpdateListener(mPositionListener);
setWillNotDraw(true);
+ mDisableBackgroundLayer = disableBackgroundLayer;
}
/**
@@ -839,7 +847,8 @@
if (mBackgroundControl == null) {
return;
}
- if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
+ if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
+ && !mDisableBackgroundLayer) {
t.show(mBackgroundControl);
} else {
t.hide(mBackgroundControl);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index eaaaa80..214da38 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -635,7 +635,7 @@
"android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
/**
- * Key used to request extra data for accessibility scanning tool's purposes.
+ * Key used to request extra data for the rendering information.
* The key requests that a {@link AccessibilityNodeInfo.ExtraRenderingInfo} be added to this
* info. This request is made with {@link #refreshWithExtraData(String, Bundle)} without
* argument.
@@ -5847,12 +5847,15 @@
}
/**
- * Gets the size object containing the height and the width of layout params if the node is
- * a {@link ViewGroup} or a {@link TextView}, or null otherwise. Useful for accessibility
- * scanning tool to understand whether the text is scalable and fits the view or not.
+ * Gets the size object containing the height and the width of
+ * {@link android.view.ViewGroup.LayoutParams} if the node is a {@link ViewGroup} or
+ * a {@link TextView}, or null otherwise. Useful for some accessibility services to
+ * understand whether the text is scalable and fits the view or not.
*
- * @return a {@link Size} stores layout height and layout width of the view,
- * or null otherwise.
+ * @return a {@link Size} stores layout height and layout width of the view, or null
+ * otherwise. And the size value may be in pixels,
+ * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
+ * or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
*/
public @Nullable Size getLayoutSize() {
return mLayoutSize;
@@ -5870,9 +5873,9 @@
}
/**
- * Gets the text size if the node is a {@link TextView}, or -1 otherwise. Useful for
- * accessibility scanning tool to understand whether the text is scalable and fits the view
- * or not.
+ * Gets the text size if the node is a {@link TextView}, or -1 otherwise. Useful for some
+ * accessibility services to understand whether the text is scalable and fits the view or
+ * not.
*
* @return the text size of a {@code TextView}, or -1 otherwise.
*/
@@ -5893,7 +5896,7 @@
/**
* Gets the text size unit if the node is a {@link TextView}, or -1 otherwise.
* Text size returned from {@link #getTextSizeInPx} in raw pixels may scale by factors and
- * convert from other units. Useful for accessibility scanning tool to understand whether
+ * convert from other units. Useful for some accessibility services to understand whether
* the text is scalable and fits the view or not.
*
* @return the text size unit which type is {@link TypedValue#TYPE_DIMENSION} of a
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 3112039..fbfeda6 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -751,6 +751,8 @@
}
} catch (RemoteException e) {
Log.e(TAG, "Could not figure out if there was an autofill session", e);
+ } catch (SyncResultReceiver.TimeoutException e) {
+ Log.e(TAG, "Fail to get session restore status: " + e);
}
}
}
@@ -864,7 +866,9 @@
mService.getFillEventHistory(receiver);
return receiver.getParcelableResult();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ Log.e(TAG, "Fail to get fill event history: " + e);
return null;
}
}
@@ -1477,10 +1481,13 @@
final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
try {
- mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName(), receiver);
+ mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName(),
+ receiver);
return receiver.getIntResult() == 1;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get enabled autofill services status.");
}
}
@@ -1498,6 +1505,8 @@
return receiver.getParcelableResult();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get autofill services component name.");
}
}
@@ -1522,8 +1531,9 @@
mService.getUserDataId(receiver);
return receiver.getStringResult();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return null;
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get user data id for field classification.");
}
}
@@ -1544,8 +1554,9 @@
mService.getUserData(receiver);
return receiver.getParcelableResult();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return null;
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get user data for field classification.");
}
}
@@ -1561,7 +1572,7 @@
try {
mService.setUserData(userData);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -1583,8 +1594,9 @@
mService.isFieldClassificationEnabled(receiver);
return receiver.getIntResult() == 1;
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return false;
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get field classification enabled status.");
}
}
@@ -1606,8 +1618,9 @@
mService.getDefaultFieldClassificationAlgorithm(receiver);
return receiver.getStringResult();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return null;
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get default field classification algorithm.");
}
}
@@ -1627,8 +1640,9 @@
final String[] algorithms = receiver.getStringArrayResult();
return algorithms != null ? Arrays.asList(algorithms) : Collections.emptyList();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return null;
+ throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get available field classification algorithms.");
}
}
@@ -1651,6 +1665,8 @@
return receiver.getIntResult() == 1;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get autofill supported status.");
}
}
@@ -2040,13 +2056,16 @@
}
final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
- final int resultCode;
+ int resultCode;
try {
mService.setAugmentedAutofillWhitelist(toList(packages), toList(activities),
resultReceiver);
resultCode = resultReceiver.getIntResult();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ Log.e(TAG, "Fail to get the result of set AugmentedAutofill whitelist. " + e);
+ return;
}
switch (resultCode) {
case RESULT_OK:
@@ -2283,7 +2302,7 @@
// In theory, we could ignore this error since it's not a big deal, but
// in reality, we rather crash the app anyways, as the failure could be
// a consequence of something going wrong on the server side...
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -2661,7 +2680,7 @@
try {
mService.onPendingSaveUi(operation, token);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ Log.e(TAG, "Error in onPendingSaveUi: ", e);
}
}
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 756ff78..484b1c1 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -487,6 +487,8 @@
return resultReceiver.getParcelableResult();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get service componentName.");
}
}
@@ -516,6 +518,9 @@
return resultReceiver.getParcelableResult();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ Log.e(TAG, "Fail to get service settings componentName: " + e);
+ return null;
}
}
@@ -567,9 +572,13 @@
final SyncResultReceiver resultReceiver = syncRun(
(r) -> mService.getContentCaptureConditions(mContext.getPackageName(), r));
- final ArrayList<ContentCaptureCondition> result = resultReceiver
- .getParcelableListResult();
- return toSet(result);
+ try {
+ final ArrayList<ContentCaptureCondition> result = resultReceiver
+ .getParcelableListResult();
+ return toSet(result);
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get content capture conditions.");
+ }
}
/**
@@ -639,15 +648,21 @@
public boolean isContentCaptureFeatureEnabled() {
final SyncResultReceiver resultReceiver = syncRun(
(r) -> mService.isContentCaptureFeatureEnabled(r));
- final int resultCode = resultReceiver.getIntResult();
- switch (resultCode) {
- case RESULT_CODE_TRUE:
- return true;
- case RESULT_CODE_FALSE:
- return false;
- default:
- Log.wtf(TAG, "received invalid result: " + resultCode);
- return false;
+
+ try {
+ final int resultCode = resultReceiver.getIntResult();
+ switch (resultCode) {
+ case RESULT_CODE_TRUE:
+ return true;
+ case RESULT_CODE_FALSE:
+ return false;
+ default:
+ Log.wtf(TAG, "received invalid result: " + resultCode);
+ return false;
+ }
+ } catch (SyncResultReceiver.TimeoutException e) {
+ Log.e(TAG, "Fail to get content capture feature enable status: " + e);
+ return false;
}
}
@@ -663,7 +678,7 @@
try {
mService.removeData(request);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -691,7 +706,7 @@
new DataShareAdapterDelegate(executor, dataShareWriteAdapter,
mDataShareAdapterResourceManager));
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
@@ -709,10 +724,12 @@
if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) {
throw new SecurityException(resultReceiver.getStringResult());
}
- return resultReceiver;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (SyncResultReceiver.TimeoutException e) {
+ throw new RuntimeException("Fail to get syn run result from SyncResultReceiver.");
}
+ return resultReceiver;
}
/** @hide */
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b36c71f..2d4d957 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1121,7 +1121,7 @@
final ComponentName cn = getNearbySharingComponent();
if (cn == null) return null;
- final Intent resolveIntent = new Intent();
+ final Intent resolveIntent = new Intent(originalIntent);
resolveIntent.setComponent(cn);
final ResolveInfo ri = getPackageManager().resolveActivity(
resolveIntent, PackageManager.GET_META_DATA);
@@ -1285,6 +1285,12 @@
ViewGroup parent) {
ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
R.layout.chooser_grid_preview_image, parent, false);
+
+ final ViewGroup actionRow =
+ (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
+ //TODO: addActionButton(actionRow, createCopyButton());
+ addActionButton(actionRow, createNearbyButton(targetIntent));
+
mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, true);
String action = targetIntent.getAction();
@@ -1395,10 +1401,11 @@
ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
R.layout.chooser_grid_preview_file, parent, false);
- // TODO(b/120417119): Disable file copy until after moving to sysui,
- // due to permissions issues
- //((ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row))
- // .addView(createCopyButton());
+ final ViewGroup actionRow =
+ (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
+ //TODO(b/120417119): addActionButton(actionRow, createCopyButton());
+ addActionButton(actionRow, createNearbyButton(targetIntent));
+
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
diff --git a/core/java/com/android/internal/util/SyncResultReceiver.java b/core/java/com/android/internal/util/SyncResultReceiver.java
index 00e9101..6b13582 100644
--- a/core/java/com/android/internal/util/SyncResultReceiver.java
+++ b/core/java/com/android/internal/util/SyncResultReceiver.java
@@ -182,7 +182,7 @@
}
/** @hide */
- public static final class TimeoutException extends RuntimeException {
+ public static final class TimeoutException extends Exception {
private TimeoutException(String msg) {
super(msg);
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5c444bd..9eede83 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1359,7 +1359,13 @@
}
closedir(dir);
- bool legacySymlinkCreated = false;
+ // Prepare default dirs for user 0 as user 0 always exists.
+ int result = symlink("/data/data", "/data/user/0");
+ if (result != 0) {
+ fail_fn(CREATE_ERROR("Failed to create symlink /data/user/0 %s", strerror(errno)));
+ }
+ PrepareDirIfNotPresent("/data/user_de/0", DEFAULT_DATA_DIR_PERMISSION,
+ AID_ROOT, AID_ROOT, fail_fn);
for (int i = 0; i < size; i += 3) {
std::string const & packageName = merged_data_info_list[i];
@@ -1400,17 +1406,8 @@
char internalDeUserPath[PATH_MAX];
snprintf(internalCeUserPath, PATH_MAX, "/data/user/%d", userId);
snprintf(internalDeUserPath, PATH_MAX, "/data/user_de/%d", userId);
- // If it's user 0, create a symlink /data/user/0 -> /data/data,
- // otherwise create /data/user/$USER
+ // If it's not user 0, create /data/user/$USER.
if (userId == 0) {
- if (!legacySymlinkCreated) {
- legacySymlinkCreated = true;
- int result = symlink(internalLegacyCePath, internalCeUserPath);
- if (result != 0) {
- fail_fn(CREATE_ERROR("Failed to create symlink %s %s", internalCeUserPath,
- strerror(errno)));
- }
- }
actualCePath = internalLegacyCePath;
} else {
PrepareDirIfNotPresent(internalCeUserPath, DEFAULT_DATA_DIR_PERMISSION,
@@ -1587,10 +1584,6 @@
// Fuse is ready, so we can start using fuse path.
int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0;
- if (size == 0) {
- fail_fn(CREATE_ERROR("Data package list cannot be empty"));
- }
-
// Create tmpfs on Android/obb and Android/data so these 2 dirs won't enter fuse anymore.
std::string androidObbDir = StringPrintf("/storage/emulated/%d/Android/obb", user_id);
MountAppDataTmpFs(androidObbDir, fail_fn);
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 25f9413..bf7f339 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -16,6 +16,9 @@
package android.view;
+import static android.view.InsetsController.ANIMATION_TYPE_NONE;
+import static android.view.InsetsController.ANIMATION_TYPE_USER;
+import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowInsets.Type.statusBars;
@@ -23,14 +26,18 @@
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Point;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager.BadTokenException;
@@ -122,6 +129,48 @@
}
@Test
+ public void testPendingStates() {
+ InsetsState state = new InsetsState();
+ InsetsController controller = mock(InsetsController.class);
+ InsetsSourceConsumer consumer = new InsetsSourceConsumer(
+ ITYPE_IME, state, null, controller);
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+
+ InsetsSource source = new InsetsSource(ITYPE_IME);
+ source.setFrame(0, 1, 2, 3);
+ consumer.updateSource(new InsetsSource(source));
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_USER);
+
+ // While we're animating, updates are delayed
+ source.setFrame(4, 5, 6, 7);
+ consumer.updateSource(new InsetsSource(source));
+ assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ITYPE_IME).getFrame());
+
+ // Finish the animation, now the pending frame should be applied
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+ assertTrue(consumer.notifyAnimationFinished());
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_USER);
+
+ // Animating again, updates are delayed
+ source.setFrame(8, 9, 10, 11);
+ consumer.updateSource(new InsetsSource(source));
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+
+ // Updating with the current frame triggers a different code path, verify this clears
+ // the pending 8, 9, 10, 11 frame:
+ source.setFrame(4, 5, 6, 7);
+ consumer.updateSource(new InsetsSource(source));
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+ assertFalse(consumer.notifyAnimationFinished());
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+ }
+
+ @Test
public void testRestore() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mConsumer.setControl(null, new int[1], new int[1]);
diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp
index 1b1a624..d6542de 100644
--- a/data/etc/car/Android.bp
+++ b/data/etc/car/Android.bp
@@ -122,6 +122,13 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.car.bugreport",
+ sub_dir: "permissions",
+ src: "com.android.car.bugreport.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.google.android.car.kitchensink",
sub_dir: "permissions",
src: "com.google.android.car.kitchensink.xml",
diff --git a/data/etc/car/com.android.car.bugreport.xml b/data/etc/car/com.android.car.bugreport.xml
new file mode 100644
index 0000000..432a838
--- /dev/null
+++ b/data/etc/car/com.android.car.bugreport.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<permissions>
+ <privapp-permissions package="com.android.car.bugreport">
+ <permission name="android.permission.DUMP"/>
+ <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.READ_LOGS"/>
+ <permission name="android.permission.MANAGE_USERS"/>
+ </privapp-permissions>
+ </permissions>
diff --git a/identity/java/android/security/identity/IdentityCredential.java b/identity/java/android/security/identity/IdentityCredential.java
index b351b3d..493c85a 100644
--- a/identity/java/android/security/identity/IdentityCredential.java
+++ b/identity/java/android/security/identity/IdentityCredential.java
@@ -167,25 +167,14 @@
* IntentToRetain = bool
* </pre>
*
- * <p>If the {@code sessionTranscript} parameter is not {@code null}, it must contain CBOR
- * data conforming to the following CDDL schema:
- *
- * <pre>
- * SessionTranscript = [
- * DeviceEngagementBytes,
- * EReaderKeyBytes
- * ]
- *
- * DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement) ; Bytes of DeviceEngagement
- * EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub) ; Bytes of EReaderKey.pub
- *
- * EReaderKey.Pub = COSE_Key ; Ephemeral public key provided by reader
- * </pre>
- *
- * <p>where a {@code COSE_Key} structure for the public part of the key-pair previously
- * generated by {@link #createEphemeralKeyPair()} must appear somewhere in
- * {@code DeviceEngagement} and the X and Y coordinates must both be present
- * in uncompressed form.
+ * <p>If the {@code sessionTranscript} parameter is not {@code null}, the X and Y coordinates
+ * of the public part of the key-pair previously generated by {@link #createEphemeralKeyPair()}
+ * must appear somewhere in the bytes of the CBOR. Each of these coordinates must appear
+ * encoded with the most significant bits first and use the exact amount of bits indicated by
+ * the key size of the ephemeral keys. For example, if the ephemeral key is using the P-256
+ * curve then the 32 bytes for the X coordinate encoded with the most significant bits first
+ * must appear somewhere in {@code sessionTranscript} and ditto for the 32 bytes for the Y
+ * coordinate.
*
* <p>If {@code readerAuth} is not {@code null} it must be the bytes of a {@code COSE_Sign1}
* structure as defined in RFC 8152. For the payload nil shall be used and the
diff --git a/identity/java/android/security/identity/WritableIdentityCredential.java b/identity/java/android/security/identity/WritableIdentityCredential.java
index c7aa328..305d0ea 100644
--- a/identity/java/android/security/identity/WritableIdentityCredential.java
+++ b/identity/java/android/security/identity/WritableIdentityCredential.java
@@ -56,10 +56,10 @@
* authority doesn't care about the nature of the security hardware. If called, however, this
* method must be called before {@link #personalize(PersonalizationData)}.
*
- * @param challenge is a byte array whose contents should be unique, fresh and provided by
- * the issuing authority. The value provided is embedded in the attestation
- * extension and enables the issuing authority to verify that the attestation
- * certificate is fresh.
+ * @param challenge is a non-empty byte array whose contents should be unique, fresh and
+ * provided by the issuing authority. The value provided is embedded in the
+ * attestation extension and enables the issuing authority to verify that the
+ * attestation certificate is fresh.
* @return the X.509 certificate for this credential's CredentialKey.
*/
public abstract @NonNull Collection<X509Certificate> getCredentialKeyCertificateChain(
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 323bba3..6c40116 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -32,7 +32,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.nano.GnssLogsProto.GnssLog;
import com.android.internal.location.nano.GnssLogsProto.PowerMetrics;
-import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.FrameworkStatsLog;
import java.util.ArrayList;
@@ -124,8 +124,6 @@
private long mL5SvStatusReportsUsedInFix;
/** Stats manager service for reporting atoms */
private StatsManager mStatsManager;
- /** Pull atom callback, this is called when atom pull request occurs */
- private StatsPullAtomCallbackImpl mPullAtomCallback;
/* Statds Logging Variables Section End */
public GnssMetrics(Context context, IBatteryStats stats) {
@@ -467,8 +465,8 @@
mConstellationTypes = new boolean[GnssStatus.CONSTELLATION_COUNT];
}
- /** Class for storing statistics */
- private class Statistics {
+ /** Thread-safe class for storing statistics */
+ private static class Statistics {
private int mCount;
private double mSum;
@@ -476,7 +474,7 @@
private long mLongSum;
/** Resets statistics */
- public void reset() {
+ public synchronized void reset() {
mCount = 0;
mSum = 0.0;
mSumSquare = 0.0;
@@ -484,7 +482,7 @@
}
/** Adds an item */
- public void addItem(double item) {
+ public synchronized void addItem(double item) {
mCount++;
mSum += item;
mSumSquare += item * item;
@@ -492,17 +490,17 @@
}
/** Returns number of items added */
- public int getCount() {
+ public synchronized int getCount() {
return mCount;
}
/** Returns mean */
- public double getMean() {
+ public synchronized double getMean() {
return mSum / mCount;
}
/** Returns standard deviation */
- public double getStandardDeviation() {
+ public synchronized double getStandardDeviation() {
double m = mSum / mCount;
m = m * m;
double v = mSumSquare / mCount;
@@ -513,7 +511,7 @@
}
/** Returns long sum */
- public long getLongSum() {
+ public synchronized long getLongSum() {
return mLongSum;
}
}
@@ -623,11 +621,11 @@
}
private void registerGnssStats() {
- mPullAtomCallback = new StatsPullAtomCallbackImpl();
+ StatsPullAtomCallbackImpl pullAtomCallback = new StatsPullAtomCallbackImpl();
mStatsManager.setPullAtomCallback(
FrameworkStatsLog.GNSS_STATS,
null, // use default PullAtomMetadata values
- BackgroundThread.getExecutor(), mPullAtomCallback);
+ ConcurrentUtils.DIRECT_EXECUTOR, pullAtomCallback);
}
/**
diff --git a/media/java/android/media/IMediaRouter2.aidl b/media/java/android/media/IMediaRouter2.aidl
index a8b82ba..ca14052 100644
--- a/media/java/android/media/IMediaRouter2.aidl
+++ b/media/java/android/media/IMediaRouter2.aidl
@@ -24,6 +24,8 @@
* @hide
*/
oneway interface IMediaRouter2 {
+ void notifyRouterRegistered(in List<MediaRoute2Info> currentRoutes,
+ in RoutingSessionInfo currentSystemSessionInfo);
void notifyRoutesAdded(in List<MediaRoute2Info> routes);
void notifyRoutesRemoved(in List<MediaRoute2Info> routes);
void notifyRoutesChanged(in List<MediaRoute2Info> routes);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 6634d4b..20e26cd 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -92,7 +92,7 @@
MediaRouter2Stub mStub;
@GuardedBy("sRouterLock")
- private final Map<String, RoutingController> mRoutingControllers = new ArrayMap<>();
+ private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mControllerCreationRequestCnt = new AtomicInteger(1);
@@ -230,7 +230,7 @@
Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.");
}
}
- if (mRouteCallbackRecords.size() == 0) {
+ if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()) {
try {
mMediaRouterService.unregisterRouter2(mStub);
} catch (RemoteException ex) {
@@ -470,7 +470,7 @@
List<RoutingController> result = new ArrayList<>();
result.add(0, mSystemController);
synchronized (sRouterLock) {
- result.addAll(mRoutingControllers.values());
+ result.addAll(mNonSystemRoutingControllers.values());
}
return result;
}
@@ -500,6 +500,77 @@
}
}
+ void syncRoutesOnHandler(List<MediaRoute2Info> currentRoutes,
+ RoutingSessionInfo currentSystemSessionInfo) {
+ if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
+ Log.e(TAG, "syncRoutesOnHandler: Received wrong data. currentRoutes=" + currentRoutes
+ + ", currentSystemSessionInfo=" + currentSystemSessionInfo);
+ return;
+ }
+
+ List<MediaRoute2Info> addedRoutes = new ArrayList<>();
+ List<MediaRoute2Info> removedRoutes = new ArrayList<>();
+ List<MediaRoute2Info> changedRoutes = new ArrayList<>();
+
+ synchronized (sRouterLock) {
+ List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
+ .collect(Collectors.toList());
+
+ for (String routeId : mRoutes.keySet()) {
+ if (!currentRoutesIds.contains(routeId)) {
+ // This route is removed while the callback is unregistered.
+ MediaRoute2Info route = mRoutes.get(routeId);
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ removedRoutes.add(mRoutes.get(routeId));
+ }
+ }
+ }
+
+ for (MediaRoute2Info route : currentRoutes) {
+ if (mRoutes.containsKey(route.getId())) {
+ if (!route.equals(mRoutes.get(route.getId()))) {
+ // This route is changed while the callback is unregistered.
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(
+ mDiscoveryPreference.getPreferredFeatures())) {
+ changedRoutes.add(route);
+ }
+ }
+ } else {
+ // This route is added while the callback is unregistered.
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ addedRoutes.add(route);
+ }
+ }
+ }
+
+ mRoutes.clear();
+ for (MediaRoute2Info route : currentRoutes) {
+ mRoutes.put(route.getId(), route);
+ }
+
+ mShouldUpdateRoutes = true;
+ }
+
+ if (addedRoutes.size() > 0) {
+ notifyRoutesAdded(addedRoutes);
+ }
+ if (removedRoutes.size() > 0) {
+ notifyRoutesRemoved(removedRoutes);
+ }
+ if (changedRoutes.size() > 0) {
+ notifyRoutesChanged(changedRoutes);
+ }
+
+ RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
+ mSystemController.setRoutingSessionInfo(currentSystemSessionInfo);
+ if (!oldInfo.equals(currentSystemSessionInfo)) {
+ notifyControllerUpdated(mSystemController);
+ }
+ }
+
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
// TODO(b/157874065): When onRoutesAdded is first called,
// 1) clear mRoutes before adding the routes
@@ -617,7 +688,7 @@
} else {
newController = new RoutingController(sessionInfo);
synchronized (sRouterLock) {
- mRoutingControllers.put(newController.getId(), newController);
+ mNonSystemRoutingControllers.put(newController.getId(), newController);
}
}
@@ -645,7 +716,7 @@
RoutingController matchingController;
synchronized (sRouterLock) {
- matchingController = mRoutingControllers.get(sessionInfo.getId());
+ matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
if (matchingController == null) {
@@ -674,7 +745,7 @@
final String uniqueSessionId = sessionInfo.getId();
RoutingController matchingController;
synchronized (sRouterLock) {
- matchingController = mRoutingControllers.get(uniqueSessionId);
+ matchingController = mNonSystemRoutingControllers.get(uniqueSessionId);
}
if (matchingController == null) {
@@ -1232,23 +1303,34 @@
mIsReleased = true;
}
- MediaRouter2Stub stub;
synchronized (sRouterLock) {
- mRoutingControllers.remove(getId(), this);
- stub = mStub;
- }
-
- if (shouldReleaseSession && stub != null) {
- try {
- mMediaRouterService.releaseSessionWithRouter2(stub, getId());
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to release session", ex);
+ if (!mNonSystemRoutingControllers.remove(getId(), this)) {
+ Log.w(TAG, "releaseInternal: Ignoring unknown controller.");
+ return false;
}
- }
- if (shouldNotifyStop) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
- RoutingController.this));
+ if (shouldReleaseSession && mStub != null) {
+ try {
+ mMediaRouterService.releaseSessionWithRouter2(mStub, getId());
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to release session", ex);
+ }
+ }
+
+ if (shouldNotifyStop) {
+ mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
+ RoutingController.this));
+ }
+
+ if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()
+ && mStub != null) {
+ try {
+ mMediaRouterService.unregisterRouter2(mStub);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "releaseInternal: Unable to unregister media router.", ex);
+ }
+ mStub = null;
+ }
}
return true;
}
@@ -1415,6 +1497,13 @@
class MediaRouter2Stub extends IMediaRouter2.Stub {
@Override
+ public void notifyRouterRegistered(List<MediaRoute2Info> currentRoutes,
+ RoutingSessionInfo currentSystemSessionInfo) {
+ mHandler.sendMessage(obtainMessage(MediaRouter2::syncRoutesOnHandler,
+ MediaRouter2.this, currentRoutes, currentSystemSessionInfo));
+ }
+
+ @Override
public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
mHandler.sendMessage(obtainMessage(MediaRouter2::addRoutesOnHandler,
MediaRouter2.this, routes));
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index a382c2d..673fffe 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -25,12 +25,14 @@
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.os.Handler;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collections;
@@ -52,6 +54,9 @@
public final class MediaRouter2Manager {
private static final String TAG = "MR2Manager";
private static final Object sLock = new Object();
+ /** @hide */
+ @VisibleForTesting
+ public static final int TRANSFER_TIMEOUT_MS = 30_000;
@GuardedBy("sLock")
private static MediaRouter2Manager sInstance;
@@ -337,30 +342,18 @@
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
Objects.requireNonNull(route, "route must not be null");
- //TODO(b/157875504): Ignore unknown route.
+ synchronized (mRoutesLock) {
+ if (!mRoutes.containsKey(route.getId())) {
+ Log.w(TAG, "transfer: Ignoring an unknown route id=" + route.getId());
+ notifyTransferFailed(sessionInfo, route);
+ return;
+ }
+ }
+
if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
transferToRoute(sessionInfo, route);
- return;
- }
-
- if (TextUtils.isEmpty(sessionInfo.getClientPackageName())) {
- Log.w(TAG, "transfer: Ignoring transfer without package name.");
- notifyTransferFailed(sessionInfo, route);
- return;
- }
-
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- //TODO(b/157875723): Ensure that every request is eventually removed. (Memory leak)
- mTransferRequests.add(new TransferRequest(requestId, sessionInfo, route));
-
- mMediaRouterService.requestCreateSessionWithManager(
- client, requestId, sessionInfo.getClientPackageName(), route);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to select media route", ex);
- }
+ } else {
+ requestCreateSession(sessionInfo, route);
}
}
@@ -523,8 +516,8 @@
continue;
}
if (sessionInfo.getSelectedRoutes().contains(request.mTargetRoute.getId())) {
- notifyTransferred(request.mOldSessionInfo, sessionInfo);
mTransferRequests.remove(request);
+ notifyTransferred(request.mOldSessionInfo, sessionInfo);
break;
}
}
@@ -595,7 +588,7 @@
public List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
- synchronized (sLock) {
+ synchronized (mRoutesLock) {
return sessionInfo.getSelectedRoutes().stream().map(mRoutes::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
@@ -611,7 +604,7 @@
List<String> selectedRouteIds = sessionInfo.getSelectedRoutes();
- synchronized (sLock) {
+ synchronized (mRoutesLock) {
return sessionInfo.getSelectableRoutes().stream()
.filter(routeId -> !selectedRouteIds.contains(routeId))
.map(mRoutes::get)
@@ -629,7 +622,7 @@
List<String> selectedRouteIds = sessionInfo.getSelectedRoutes();
- synchronized (sLock) {
+ synchronized (mRoutesLock) {
return sessionInfo.getDeselectableRoutes().stream()
.filter(routeId -> selectedRouteIds.contains(routeId))
.map(mRoutes::get)
@@ -725,41 +718,6 @@
}
/**
- * Transfers to a given route for the remote session.
- *
- * @hide
- */
- void transferToRoute(@NonNull RoutingSessionInfo sessionInfo,
- @NonNull MediaRoute2Info route) {
- Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
- Objects.requireNonNull(route, "route must not be null");
-
- if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
- Log.w(TAG, "Ignoring transferring to a route that is already added. route="
- + route);
- return;
- }
-
- if (!sessionInfo.getTransferableRoutes().contains(route.getId())) {
- Log.w(TAG, "Ignoring transferring to a non-transferable route=" + route);
- return;
- }
-
- int requestId = mNextRequestId.getAndIncrement();
- mTransferRequests.add(new TransferRequest(requestId, sessionInfo, route));
-
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- mMediaRouterService.transferToRouteWithManager(
- client, requestId, sessionInfo.getId(), route);
- } catch (RemoteException ex) {
- Log.e(TAG, "transferToRoute: Failed to send a request.", ex);
- }
- }
- }
-
- /**
* Requests releasing a session.
* <p>
* If a session is released, any operation on the session will be ignored.
@@ -784,6 +742,65 @@
}
}
+ /**
+ * Transfers the remote session to the given route.
+ *
+ * @hide
+ */
+ private void transferToRoute(@NonNull RoutingSessionInfo session,
+ @NonNull MediaRoute2Info route) {
+ int requestId = createTransferRequest(session, route);
+
+ Client client = getOrCreateClient();
+ if (client != null) {
+ try {
+ mMediaRouterService.transferToRouteWithManager(
+ client, requestId, session.getId(), route);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "transferToRoute: Failed to send a request.", ex);
+ }
+ }
+ }
+
+ private void requestCreateSession(RoutingSessionInfo oldSession, MediaRoute2Info route) {
+ if (TextUtils.isEmpty(oldSession.getClientPackageName())) {
+ Log.w(TAG, "requestCreateSession: Can't create a session without package name.");
+ notifyTransferFailed(oldSession, route);
+ return;
+ }
+
+ int requestId = createTransferRequest(oldSession, route);
+
+ Client client = getOrCreateClient();
+ if (client != null) {
+ try {
+ mMediaRouterService.requestCreateSessionWithManager(
+ client, requestId, oldSession.getClientPackageName(), route);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "requestCreateSession: Failed to send a request", ex);
+ }
+ }
+ }
+
+ private int createTransferRequest(RoutingSessionInfo session, MediaRoute2Info route) {
+ int requestId = mNextRequestId.getAndIncrement();
+ TransferRequest transferRequest = new TransferRequest(requestId, session, route);
+ mTransferRequests.add(transferRequest);
+
+ Message timeoutMessage =
+ obtainMessage(MediaRouter2Manager::handleTransferTimeout, this, transferRequest);
+ mHandler.sendMessageDelayed(timeoutMessage, TRANSFER_TIMEOUT_MS);
+ return requestId;
+ }
+
+ private void handleTransferTimeout(TransferRequest request) {
+ boolean removed = mTransferRequests.remove(request);
+ if (removed) {
+ notifyTransferFailed(request.mOldSessionInfo, request.mTargetRoute);
+ }
+ }
+
+
private boolean areSessionsMatched(MediaController mediaController,
RoutingSessionInfo sessionInfo) {
MediaController.PlaybackInfo playbackInfo = mediaController.getPlaybackInfo();
@@ -905,7 +922,7 @@
if (!(obj instanceof CallbackRecord)) {
return false;
}
- return mCallback == ((CallbackRecord) obj).mCallback;
+ return mCallback == ((CallbackRecord) obj).mCallback;
}
@Override
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 26e65dd..1bf2863 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -16,28 +16,22 @@
package android.media;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.lang.ref.WeakReference;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityThread;
-import android.app.AppOpsManager;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
-import android.media.PlayerBase;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.util.AndroidRuntimeException;
import android.util.Log;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.atomic.AtomicReference;
+
/**
* The SoundPool class manages and plays audio resources for applications.
@@ -122,13 +116,12 @@
private final static String TAG = "SoundPool";
private final static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private final AtomicReference<EventHandler> mEventHandler = new AtomicReference<>(null);
+
private long mNativeContext; // accessed by native methods
- private EventHandler mEventHandler;
- private SoundPool.OnLoadCompleteListener mOnLoadCompleteListener;
private boolean mHasAppOpsPlayAudio;
- private final Object mLock;
private final AudioAttributes mAttributes;
/**
@@ -159,7 +152,6 @@
if (native_setup(new WeakReference<SoundPool>(this), maxStreams, attributes) != 0) {
throw new RuntimeException("Native setup failed");
}
- mLock = new Object();
mAttributes = attributes;
baseRegisterPlayer();
@@ -491,21 +483,18 @@
* Sets the callback hook for the OnLoadCompleteListener.
*/
public void setOnLoadCompleteListener(OnLoadCompleteListener listener) {
- synchronized(mLock) {
- if (listener != null) {
- // setup message handler
- Looper looper;
- if ((looper = Looper.myLooper()) != null) {
- mEventHandler = new EventHandler(looper);
- } else if ((looper = Looper.getMainLooper()) != null) {
- mEventHandler = new EventHandler(looper);
- } else {
- mEventHandler = null;
- }
- } else {
- mEventHandler = null;
- }
- mOnLoadCompleteListener = listener;
+ if (listener == null) {
+ mEventHandler.set(null);
+ return;
+ }
+
+ Looper looper;
+ if ((looper = Looper.myLooper()) != null) {
+ mEventHandler.set(new EventHandler(looper, listener));
+ } else if ((looper = Looper.getMainLooper()) != null) {
+ mEventHandler.set(new EventHandler(looper, listener));
+ } else {
+ mEventHandler.set(null);
}
}
@@ -525,35 +514,36 @@
@SuppressWarnings("unchecked")
private static void postEventFromNative(Object ref, int msg, int arg1, int arg2, Object obj) {
SoundPool soundPool = ((WeakReference<SoundPool>) ref).get();
- if (soundPool == null)
+ if (soundPool == null) {
return;
-
- if (soundPool.mEventHandler != null) {
- Message m = soundPool.mEventHandler.obtainMessage(msg, arg1, arg2, obj);
- soundPool.mEventHandler.sendMessage(m);
}
+
+ Handler eventHandler = soundPool.mEventHandler.get();
+ if (eventHandler == null) {
+ return;
+ }
+
+ Message message = eventHandler.obtainMessage(msg, arg1, arg2, obj);
+ eventHandler.sendMessage(message);
}
private final class EventHandler extends Handler {
- public EventHandler(Looper looper) {
+ private final OnLoadCompleteListener mOnLoadCompleteListener;
+
+ EventHandler(Looper looper, @NonNull OnLoadCompleteListener onLoadCompleteListener) {
super(looper);
+ mOnLoadCompleteListener = onLoadCompleteListener;
}
@Override
public void handleMessage(Message msg) {
- switch(msg.what) {
- case SAMPLE_LOADED:
- if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded");
- synchronized(mLock) {
- if (mOnLoadCompleteListener != null) {
- mOnLoadCompleteListener.onLoadComplete(SoundPool.this, msg.arg1, msg.arg2);
- }
- }
- break;
- default:
+ if (msg.what != SAMPLE_LOADED) {
Log.e(TAG, "Unknown message type " + msg.what);
return;
}
+
+ if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded");
+ mOnLoadCompleteListener.onLoadComplete(SoundPool.this, msg.arg1, msg.arg2);
}
}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index 1e49f49..356acdc 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -17,6 +17,7 @@
package com.android.mediaroutertest;
import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
+import static android.media.MediaRoute2Info.FEATURE_REMOTE_PLAYBACK;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
import static android.media.MediaRoute2ProviderService.REASON_REJECTED;
@@ -28,6 +29,7 @@
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID2;
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
+import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID6_TO_BE_IGNORED;
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME;
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME;
@@ -51,6 +53,7 @@
import android.media.RoutingSessionInfo;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils;
@@ -79,6 +82,8 @@
private static final int TIMEOUT_MS = 5000;
private static final String TEST_KEY = "test_key";
private static final String TEST_VALUE = "test_value";
+ private static final String TEST_ID_UNKNOWN = "id_unknown";
+ private static final String TEST_NAME_UNKNOWN = "unknown";
private Context mContext;
private MediaRouter2Manager mManager;
@@ -309,6 +314,36 @@
assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
}
+ @Test
+ public void testTransfer_unknownRoute_fail() throws Exception {
+ addRouterCallback(new RouteCallback() {});
+
+ CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
+ CountDownLatch onTransferFailedLatch = new CountDownLatch(1);
+
+ addManagerCallback(new MediaRouter2Manager.Callback() {
+ @Override
+ public void onTransferred(RoutingSessionInfo oldSessionInfo,
+ RoutingSessionInfo newSessionInfo) {
+ assertNotNull(newSessionInfo);
+ onSessionCreatedLatch.countDown();
+ }
+ @Override
+ public void onTransferFailed(RoutingSessionInfo session, MediaRoute2Info route) {
+ onTransferFailedLatch.countDown();
+ }
+ });
+
+ MediaRoute2Info unknownRoute =
+ new MediaRoute2Info.Builder(TEST_ID_UNKNOWN, TEST_NAME_UNKNOWN)
+ .addFeature(FEATURE_REMOTE_PLAYBACK)
+ .build();
+
+ mManager.transfer(mManager.getSystemRoutingSession(), unknownRoute);
+ assertFalse(onSessionCreatedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertTrue(onTransferFailedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
/**
* Tests select, transfer, release of routes of a provider
*/
@@ -350,6 +385,35 @@
}
@Test
+ @LargeTest
+ public void testTransfer_ignored_fails() throws Exception {
+ Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
+ addRouterCallback(new RouteCallback() {});
+
+ CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
+ CountDownLatch onFailedLatch = new CountDownLatch(1);
+
+ addManagerCallback(new MediaRouter2Manager.Callback() {
+ @Override
+ public void onTransferred(RoutingSessionInfo oldSessionInfo,
+ RoutingSessionInfo newSessionInfo) {
+ onSessionCreatedLatch.countDown();
+ }
+ @Override
+ public void onTransferFailed(RoutingSessionInfo session, MediaRoute2Info route) {
+ onFailedLatch.countDown();
+ }
+ });
+
+ List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
+ RoutingSessionInfo targetSession = sessions.get(sessions.size() - 1);
+ mManager.transfer(targetSession, routes.get(ROUTE_ID6_TO_BE_IGNORED));
+
+ assertFalse(onSessionCreatedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertTrue(onFailedLatch.await(MediaRouter2Manager.TRANSFER_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS));
+ }
+ @Test
public void testSetSystemRouteVolume() throws Exception {
// ensure client
addManagerCallback(new MediaRouter2Manager.Callback());
@@ -639,8 +703,10 @@
mRouter2.registerRouteCallback(mExecutor, routeCallback,
new RouteDiscoveryPreference.Builder(routeFeatures, true).build());
try {
- addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- featuresLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (mManager.getAllRoutes().isEmpty()) {
+ addedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+ }
+ featuresLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
return createRouteMap(mManager.getAvailableRoutes(mPackageName));
} finally {
mRouter2.unregisterRouteCallback(routeCallback);
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java
index 4e398f2..4551876 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java
@@ -53,6 +53,9 @@
public static final String ROUTE_ID5_TO_TRANSFER_TO = "route_id5_to_transfer_to";
public static final String ROUTE_NAME5 = "Sample Route 5 - Route to transfer to";
+ public static final String ROUTE_ID6_TO_BE_IGNORED = "route_id6_to_be_ignored";
+ public static final String ROUTE_NAME6 = "Sample Route 6 - Route to be ignored";
+
public static final String ROUTE_ID_SPECIAL_FEATURE = "route_special_feature";
public static final String ROUTE_NAME_SPECIAL_FEATURE = "Special Feature Route";
@@ -98,7 +101,10 @@
ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5)
.addFeature(FEATURE_SAMPLE)
.build();
-
+ MediaRoute2Info route6 = new MediaRoute2Info.Builder(
+ ROUTE_ID6_TO_BE_IGNORED, ROUTE_NAME6)
+ .addFeature(FEATURE_SAMPLE)
+ .build();
MediaRoute2Info routeSpecial =
new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE)
.addFeature(FEATURE_SAMPLE)
@@ -121,6 +127,7 @@
mRoutes.put(route3.getId(), route3);
mRoutes.put(route4.getId(), route4);
mRoutes.put(route5.getId(), route5);
+ mRoutes.put(route6.getId(), route6);
mRoutes.put(routeSpecial.getId(), routeSpecial);
mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute);
@@ -219,6 +226,10 @@
notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR);
return;
}
+ // Ignores the request intentionally for testing
+ if (TextUtils.equals(ROUTE_ID6_TO_BE_IGNORED, routeId)) {
+ return;
+ }
maybeDeselectRoute(routeId);
final String sessionId = String.valueOf(mNextSessionId);
diff --git a/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml b/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
deleted file mode 100644
index 696e9b1..0000000
--- a/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2016 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ 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
- -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:color="?android:attr/textColorPrimary" />
- <item android:color="@android:color/transparent" />
-</selector>
diff --git a/packages/SystemUI/res/drawable/ic_error_outline.xml b/packages/SystemUI/res/drawable/ic_error_outline.xml
new file mode 100644
index 0000000..140180a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_error_outline.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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:fillColor="#FF000000"
+ android:pathData="M11,15h2v2h-2v-2zM11,7h2v6h-2L11,7zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_power.xml b/packages/SystemUI/res/drawable/ic_settings_power.xml
new file mode 100644
index 0000000..137c289
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_settings_power.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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="M8,24c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1 -1,0.45 -1,1 0.45,1 1,1zM12,24c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1 -1,0.45 -1,1 0.45,1 1,1zM13,2h-2v10h2L13,2zM16.56,4.44l-1.45,1.45C16.84,6.94 18,8.83 18,11c0,3.31 -2.69,6 -6,6s-6,-2.69 -6,-6c0,-2.17 1.16,-4.06 2.88,-5.12L7.44,4.44C5.36,5.88 4,8.28 4,11c0,4.42 3.58,8 8,8s8,-3.58 8,-8c0,-2.72 -1.36,-5.12 -3.44,-6.56zM16,24c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1 -1,0.45 -1,1 0.45,1 1,1z"
+ android:fillColor="#000000"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout-sw600dp/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout-sw600dp/keyguard_user_switcher_item.xml
index 4413b1e..9ce030e 100644
--- a/packages/SystemUI/res/layout-sw600dp/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/keyguard_user_switcher_item.xml
@@ -27,13 +27,13 @@
android:gravity="end|center_vertical"
android:clickable="true"
android:background="@drawable/kg_user_switcher_rounded_bg"
+ sysui:activatedTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher"
sysui:regularTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher">
<TextView android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
android:layout_marginEnd="12dp"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher"
/>
<com.android.systemui.statusbar.phone.UserAvatarView android:id="@+id/user_picture"
android:layout_width="@dimen/kg_framed_avatar_size"
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
index a46823d..da5277c 100644
--- a/packages/SystemUI/res/layout/global_screenshot_static.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -53,15 +53,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</HorizontalScrollView>
- <ImageView
- android:id="@+id/global_screenshot_animated_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:visibility="gone"
- android:elevation="@dimen/screenshot_preview_elevation"
- android:background="@drawable/screenshot_rounded_corners"
- android:adjustViewBounds="true"/>
<include layout="@layout/global_screenshot_preview"/>
<FrameLayout
android:id="@+id/global_screenshot_dismiss_button"
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
index 626951c..1cd1a04 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
@@ -39,8 +39,6 @@
android:layout_width="@dimen/kg_framed_avatar_size"
android:layout_height="@dimen/kg_framed_avatar_size"
android:contentDescription="@null"
- android:backgroundTint="@color/qs_user_detail_avatar_tint"
- android:backgroundTintMode="src_atop"
sysui:frameWidth="@dimen/keyguard_user_switcher_border_thickness"
sysui:framePadding="2.5dp"
sysui:badgeDiameter="18dp"
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index 0608685..cc6c5d3 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -30,6 +30,7 @@
android:clipToPadding="false"
android:focusable="true"
android:background="@drawable/ripple_drawable"
+ systemui:activatedTextAppearance="@style/TextAppearance.QS.UserSwitcher"
systemui:regularTextAppearance="@style/TextAppearance.QS.UserSwitcher">
<com.android.systemui.statusbar.phone.UserAvatarView
@@ -37,8 +38,6 @@
android:layout_width="@dimen/qs_framed_avatar_size"
android:layout_height="@dimen/qs_framed_avatar_size"
android:layout_marginBottom="7dp"
- android:backgroundTint="@color/qs_user_detail_avatar_tint"
- android:backgroundTintMode="src_atop"
systemui:frameWidth="6dp"
systemui:badgeDiameter="18dp"
systemui:badgeMargin="1dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 45d4cb4..befd602 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swiep om meer te sien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laai tans aanbevelings"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Maak hierdie mediasessie toe"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout, probeer tans weer …"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Toestel is verwyder"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Kon nie by <xliff:g id="DEVICE">%1$s</xliff:g> ingaan nie. Gaan die <xliff:g id="APPLICATION">%2$s</xliff:g>-program na om seker te maak dat die kontrole steeds beskikbaar is en dat die programinstellings nie verander het nie."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Maak program oop"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Kan nie status laai nie"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer weer"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Besig"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a88be36..77ef16d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ተጨማሪ ለማየት ያንሸራትቱ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ምክሮችን በመጫን ላይ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ይህን የሚዲያ ክፍለ-ጊዜ ዝጋ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ስህተት፣ እንደገና በመሞከር ላይ…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"መሣሪያ ተወግዷል"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"ሁኔታን መጫን አልተቻልም"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ስህተት፣ እንደገና ይሞክሩ"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"በሂደት ላይ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 2a0af5d..3ff3616 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1086,9 +1086,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مرّر سريعًا لرؤية المزيد."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"جارٍ تحميل الاقتراحات"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"إغلاق جلسة تشغيل الوسائط هذه"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"حدث خطأ، جارٍ إعادة المحاولة…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"تمت إزالة الجهاز."</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"يتعذّر تحميل الحالة."</string>
<string name="controls_error_failed" msgid="960228639198558525">"حدث خطأ، يُرجى إعادة المحاولة."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"قيد التقدم"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index e3fd2cb..2bfafd6 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"অধিক চাবলৈ ছোৱাইপ কৰক"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"এই মিডিয়া ছেশ্বনটো বন্ধ কৰক"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"আসোঁৱাহ, পুনৰ চেষ্টা কৰি আছে…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ডিভাইচটো আঁতৰোৱা হৈছে"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> এক্সেছ কৰিব পৰা নগ’ল। নিয়ন্ত্ৰণটো যে এতিয়াও উপলব্ধ আৰু এপ্টোৰ ছেটিংসমূহ সলনি কৰা হোৱা নাই বুলি নিশ্চিত কৰিবলৈ <xliff:g id="APPLICATION">%2$s</xliff:g> এপ্টো পৰীক্ষা কৰক।"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"এপ্টো খোলক"</string>
<string name="controls_error_generic" msgid="352500456918362905">"স্থিতি ল’ড কৰিব নোৱাৰি"</string>
<string name="controls_error_failed" msgid="960228639198558525">"আসোঁৱাহ হৈছে, আকৌ চেষ্টা কৰক"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"চলি আছে"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 0adee8c..1a0bb2b 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Digərlərini görmək üçün sürüşdürün"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tövsiyələr yüklənir"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Bu media sessiyasını bağlayın"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xəta, yenidən cəhd edilir…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Cihaz silindi"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Statusu yükləmək alınmadı"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Xəta, yenidən cəhd edin"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Davam edir"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 868d1cb..6be6e74 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1068,9 +1068,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zatvorite ovu sesiju medija"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, pokušava se ponovo…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Uređaj je uklonjen"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Učitavanje statusa nije uspelo"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Greška. Probajte ponovo"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"U toku"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 04cd56a..273ee2d 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Правядзіце пальцам, каб убачыць больш інфармацыі"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загружаюцца рэкамендацыі"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Закрыць гэты сеанс мультымедыя"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Памылка, паўторная спроба…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Прылада выдалена"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Не ўдалося загрузіць стан"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Памылка, паўтарыце спробу"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Выконваецца"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 034217c..ea31b32 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Затваряне на тази сесия за мултимедия"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка. Извършва се нов опит…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Устройството бе премахнато"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Състоян. не може да се зареди"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Грешка. Опитайте отново"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"В ход"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 7482dfe..2824221 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"আরও দেখতে সোয়াইপ করুন"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"এই মিডিয়া সেশন বেছে নিন"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"সমস্যা, আবার চেষ্টা করা হচ্ছে…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ডিভাইস সরিয়ে দেওয়া হয়েছে"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ডিভাইস অ্যাক্সেস করা যায়নি। <xliff:g id="APPLICATION">%2$s</xliff:g> অ্যাপ চেক করে দেখুন যাতে এটি নিশ্চিত করে নিতে পারেন যে কন্ট্রোল এখনও উপলভ্য আছে এবং অ্যাপ সেটিংসে কোনও পরিবর্তন করা হয়নি।"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"অ্যাপ খুলুন"</string>
<string name="controls_error_generic" msgid="352500456918362905">"স্ট্যাটাস লোড করা যাচ্ছে না"</string>
<string name="controls_error_failed" msgid="960228639198558525">"সমস্যা হয়েছে, আবার চেষ্টা করুন"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"চলছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index c049c5f..fc5e0a1 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1070,9 +1070,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zatvori ovu medijsku sesiju"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, ponovni pokušaj…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Uređaj je uklonjen"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Nije moguće učitati status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Greška, pokušajte ponovo"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"U toku"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 506429c..2d1c9ca 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Llisca per veure\'n més"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Tanca aquesta sessió multimèdia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error. S\'està tornant a provar…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"El dispositiu s\'ha suprimit"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"No es pot carregar l\'estat"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error; torna-ho a provar"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En curs"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 48ab79e..d964b03 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Přejetím prstem zobrazíte další položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítání doporučení"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zavřít tuto mediální relaci"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba. Nový pokus…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Zařízení bylo odebráno"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Stav nelze načíst"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Chyba, zkuste to znovu"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Probíhá"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 8d2d5c5..17dcea1 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Stryg for at se mere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Indlæser anbefalinger"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Luk denne mediesession"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fejl. Prøver igen…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Enheden er fjernet"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Statussen kan ikke indlæses"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Der opstod en fejl. Prøv igen"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"I gang"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 50cb3f3..92c30fc 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Diese Mediensitzung schließen"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fehler. Neuer Versuch…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Gerät entfernt"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Status kann nicht geladen werden"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Fehler – versuch es noch mal"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Läuft"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 6a32d57..2277e21 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Σύρετε για να δείτε περισσότερα."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Κλείσιμο αυτής της περιόδου λειτουργίας μέσων."</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Προέκυψε σφάλμα. Επανάληψη…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Η συσκευή καταργήθηκε"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Αδυναμία φόρτωσης κατάστασης"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Σφάλμα, προσπαθήστε ξανά."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Σε εξέλιξη"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 35f09af..f439791 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Device removed"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure that the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In progress"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 8c8db6a..d6e74f0 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Device removed"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure that the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In progress"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 35f09af..f439791 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Device removed"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure that the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In progress"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 35f09af..f439791 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Device removed"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure that the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In progress"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index e514ccb..d961e10 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -1062,10 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
- <!-- no translation found for controls_error_removed (6299213591234723805) -->
- <skip />
+ <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In progress"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b1a7427..8cf78e8 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1013,17 +1013,14 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
- <!-- no translation found for priority_onboarding_title (2893070698479227616) -->
- <skip />
- <!-- no translation found for priority_onboarding_behavior (5342816047020432929) -->
- <skip />
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"Se estableció la conversación como prioritaria"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Las conversaciones prioritarias harán lo siguiente:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Se muestran en la parte superior de conversaciones"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran una foto de perfil en pantalla de bloqueo"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbujas flotantes encima de apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Suspender No interrumpir"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
- <!-- no translation found for priority_onboarding_settings_button_title (6663601574303585927) -->
- <skip />
+ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configuración"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"Ventana superpuesta de ampliación"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Controles de ampliación de la ventana"</string>
@@ -1065,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más elementos"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Cerrar esta sesión multimedia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hubo un error. Reintentando…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Se quitó el dispositivo"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"No se pudo cargar el estado"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error. Vuelve a intentarlo."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En curso"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f210fbb..1f64d57 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1016,7 +1016,7 @@
<string name="priority_onboarding_title" msgid="2893070698479227616">"Conversación marcada como prioritaria"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Las conversaciones prioritarias:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Se muestran en la parte superior de la sección de conversaciones"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran tu imagen de perfil en la pantalla de bloqueo"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran la imagen de perfil en la pantalla de bloqueo"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbuja sobre las aplicaciones"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrumpen el modo No molestar"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Cerrar esta sesión multimedia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error; reintentando…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispositivo quitado"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"No se ha podido cargar el estado"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Se ha producido un error. Vuelve a intentarlo."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En curso"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 0d640e1..a334d67 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Sulge see meediaseanss"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Viga, proovitakse uuesti …"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Seade on eemaldatud"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Olekut ei saa laadida"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ilmnes viga, proovige uuesti"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Pooleli"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 1cb3148..e7e5467 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1062,9 +1062,14 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Itxi multimedia-saio hau"</string>
+ <!-- no translation found for controls_media_resume (1933520684481586053) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errorea. Berriro saiatzen…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Gailua kendu da"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago kontrolatzeko aukera"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Ezin izan da atzitu <xliff:g id="DEVICE">%1$s</xliff:g>. Joan <xliff:g id="APPLICATION">%2$s</xliff:g> aplikaziora eta ziurtatu kontrolatzeko aukera oraindik ere erabilgarri dagoela eta aplikazioaren ezarpenak aldatu ez direla."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Ireki aplikazioa"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Ezin da kargatu egoera"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Errorea. Saiatu berriro."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Abian"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 986015e..bb1b755 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"برای دیدن موارد بیشتر، تند بکشید"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"درحال بار کردن توصیهها"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"بستن این جلسه رسانه"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خطا، درحال تلاش مجدد…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"دستگاه برداشته شد"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"وضعیت بار نشد"</string>
<string name="controls_error_failed" msgid="960228639198558525">"خطا، دوباره امتحان کنید"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"درحال انجام"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index be04730..dc7338f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pyyhkäise nähdäksesi lisää"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ladataan suosituksia"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Sulje tämä median käyttökerta"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Virhe, yritetään uudelleen…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Laite poistettu"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Tilaa ei voi ladata"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Virhe, yritä uudelleen"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Käynnissä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a80e2d3..d0affae 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayez l\'écran pour en afficher davantage"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations…"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Fermer cette session multimédia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur, nouvelle tentative…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Appareil supprimé"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Impossible d\'accéder à <xliff:g id="DEVICE">%1$s</xliff:g>. Vérifiez l\'application <xliff:g id="APPLICATION">%2$s</xliff:g> pour vous assurer que la commande est toujours offerte et que les paramètres de l\'application n\'ont pas changé."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Ouvrir l\'application"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Impossible de charger l\'état"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En cours"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b95cf57..bfbca25 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayer l\'écran pour voir plus d\'annonces"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Fermer cette session multimédia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur. Nouvelle tentative…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Appareil supprimé"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Impossible de charger l\'état"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En cours"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 960e416..e7f490d 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasar o dedo para ver máis"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendacións"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Pechar esta sesión multimedia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando de novo…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Quitouse o dispositivo"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Non se puido cargar o estado"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erro. Téntao de novo"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En curso"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 4936b7b..ccfd903 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"વધુ જોવા માટે સ્વાઇપ કરો"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"આ મીડિયા સત્રને બંધ કરો"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ભૂલ, ફરી પ્રયાસ કરી રહ્યા છીએ…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ડિવાઇસ કાઢી નાખ્યું"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ને ઍક્સેસ કરી શક્યાં નહીં. નિયંત્રણ હજી પણ ઉપલબ્ધ છે અને તે કે ઍપના સેટિંગ બદલાયા નથી તેની ખાતરી કરવા માટે <xliff:g id="APPLICATION">%2$s</xliff:g> ઍપ ચેક કરો."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ઍપ ખોલો"</string>
<string name="controls_error_generic" msgid="352500456918362905">"સ્ટેટસ લોડ કરી શકાતું નથી"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ભૂલ, ફરીથી પ્રયાસ કરો"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"પ્રક્રિયા ચાલુ છે"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 1fcfcc4..83b4be8 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1064,9 +1064,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ज़्यादा देखने के लिए स्वाइप करें"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सुझाव लोड हो रहे हैं"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"इस मीडिया सेशन को बंद करें"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"कोई गड़बड़ी हुई, फिर से कोशिश की जा रही है…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"डिवाइस हटाया गया"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"स्थिति लोड नहीं की जा सकती"</string>
<string name="controls_error_failed" msgid="960228639198558525">"गड़बड़ी हुई, फिर से कोशिश करें"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"जारी है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c918dca..0920b6f 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1068,9 +1068,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prijeđite prstom da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zatvorite ovu medijsku sesiju"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Pogreška, pokušavamo ponovo…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Uređaj je uklonjen"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Status se ne može učitati"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Pogreška, pokušajte ponovo"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"U tijeku"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 2a991f1..e40c967 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Továbbiak megtekintéséhez csúsztasson"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Javaslatok betöltése…"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Médiamunkamenet bezárása"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hiba, újrapróbálkozás…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Eszköz eltávolítva"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Állapot betöltése sikertelen"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Hiba történt. Próbálja újra."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Folyamatban"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 908231a..18ab862 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Սահեցրեք մատը՝ ավելին իմանալու համար"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Փակել աշխատաշրջանը"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Վերսկսել"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Սխալ. նորից ենք փորձում…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Սարքը հեռացված է"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Կառավարման տարրը հասանելի չէ"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> սարքն անհասանելի է։ Ստուգեք <xliff:g id="APPLICATION">%2$s</xliff:g> հավելվածը՝ համոզվելու, որ կառավարման տարրը դեռ հասանելի է և հավելվածի կարգավորումները չեն փոխվել։"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Բացել հավելվածը"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Չհաջողվեց բեռնել կարգավիճակը"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Սխալ առաջացավ։ Նորից փորձեք։"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Ընթացքի մեջ է"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 2e11e42..1935c02 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Geser untuk melihat selengkapnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Tutup sesi media ini"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, mencoba lagi..."</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Perangkat dihapus"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Tidak dapat mengakses <xliff:g id="DEVICE">%1$s</xliff:g>. Periksa aplikasi <xliff:g id="APPLICATION">%2$s</xliff:g> untuk memastikan kontrol masih tersedia dan bahwa setelan aplikasi tidak berubah."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Buka aplikasi"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Tidak dapat memuat status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, coba lagi"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Dalam proses"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 773bda7..d2fb09c 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Strjúktu til að sjá meira"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Hleður tillögum"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Loka þessari efnislotu"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Villa, reynir aftur…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Tæki fjarlægt"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Ekki er hægt að hlaða stöðu"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Villa, reyndu aftur"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Í gangi"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 0844284..c32f847 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Scorri per vedere altro"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Caricamento dei consigli"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Chiudi questa sessione multimediale"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errore. Nuovo tentativo…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispositivo rimosso"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Impossibile caricare lo stato"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Errore. Riprova"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In corso"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f23254a..683e7e0 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1023,17 +1023,14 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string>
- <!-- no translation found for priority_onboarding_title (2893070698479227616) -->
- <skip />
- <!-- no translation found for priority_onboarding_behavior (5342816047020432929) -->
- <skip />
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"השיחה הוגדרה כבעלת עדיפות גבוהה"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"שיחות בעדיפות גבוהה:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"מופיעות בחלק העליון של קטע השיחות"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"מציגות תמונת פרופיל במסך הנעילה"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"מופיעות כבועה צפה מעל האפליקציות שלך"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"גוברות על ההגדרה \'נא לא להפריע\'"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"הבנתי"</string>
- <!-- no translation found for priority_onboarding_settings_button_title (6663601574303585927) -->
- <skip />
+ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"הגדרות"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"חלון ליצירת שכבת-על להגדלה"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"חלון הגדלה"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"בקרות של חלון ההגדלה"</string>
@@ -1077,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"יש להחליק כדי להציג עוד פריטים"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"בטעינת המלצות"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"סגירת הסשן הזה של המדיה"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"שגיאה, מתבצע ניסיון חוזר…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"המכשיר הוסר"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"לא ניתן לטעון את הסטטוס"</string>
<string name="controls_error_failed" msgid="960228639198558525">"שגיאה, יש לנסות שוב"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"בתהליך"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6e7555a..f8fbce4 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"スワイプすると他の構造が表示されます"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"このメディア セッションを閉じる"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"エラー。再試行しています…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"デバイスを削除しました"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"ステータスを読み込めません"</string>
<string name="controls_error_failed" msgid="960228639198558525">"エラー: もう一度お試しください"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"処理中"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 4aea87b..4935094 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"გადაფურცლეთ მეტის სანახავად"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"მიმდინარეობს რეკომენდაციების ჩატვირთვა"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ამ მედია სესიის დახურვა"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"შეცდომა, ხელახალი მცდელობა…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"მოწყობილობა ამოიშალა"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"სტატუსი ვერ იტვირთება"</string>
<string name="controls_error_failed" msgid="960228639198558525">"შეცდომა, ისევ ცადეთ"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"მუშავდება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index bb4ee6b..192777f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Толығырақ ақпарат алу үшін сырғытыңыз."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Мультимедиа сеансын жабу"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Қате, әрекет қайталануда…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Құрылғы өшірілді."</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Күйді жүктеу мүмкін емес."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Қате шықты. Қайталап көріңіз."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Орындалуда"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index c00549c..2a0f882 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"អូសដើម្បីមើលច្រើនទៀត"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"កំពុងផ្ទុកការណែនាំ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"បិទវគ្គមេឌៀនេះ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"បញ្ហា កំពុងព្យាយាមម្ដងទៀត…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"បានលុបឧបករណ៍"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"មិនអាចផ្ទុកស្ថានភាពបានទេ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"មានបញ្ហា សូមព្យាយាមម្តងទៀត"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"កំពុងដំណើរការ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 7b707b5..095f674 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ಇನ್ನಷ್ಟು ನೋಡಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ಶಿಫಾರಸುಗಳು ಲೋಡ್ ಆಗುತ್ತಿವೆ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ಈ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮುಚ್ಚಿರಿ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ದೋಷ, ಮರುಪ್ರಯತ್ನಿಸಲಾಗುತ್ತಿದೆ…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ಸಾಧನವನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"ನಿಯಂತ್ರಣ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಯಂತ್ರಣ ಈಗಲೂ ಲಭ್ಯವಿದೆಯೇ ಮತ್ತು <xliff:g id="APPLICATION">%2$s</xliff:g> ಆ್ಯಪ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಲಾಗಿಲ್ಲ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಆ್ಯಪ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ಆ್ಯಪ್ ತೆರೆಯಿರಿ"</string>
<string name="controls_error_generic" msgid="352500456918362905">"ಸ್ಥಿತಿ ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ದೋಷ, ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ಪ್ರಗತಿಯಲ್ಲಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 263c4dd..c33fcb1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"이 미디어 세션 닫기"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"오류 발생, 다시 시도 중…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"기기가 삭제됨"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"통계를 로드할 수 없음"</string>
<string name="controls_error_failed" msgid="960228639198558525">"오류. 다시 시도하세요."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"진행 중"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index dcd10cc..87d783b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Дагы көрүү үчүн экранды сүрүп коюңуз"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Бул медиа сеансын жабуу"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ката, дагы аракет жасалууда…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Түзмөктү көзөмөлдөө өчүрүлдү"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Абалы жүктөлгөн жок"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ката, кайталап көрүңүз"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Аткарылууда"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a7e9d8d..89b9022 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ປັດເພື່ອເບິ່ງເພີ່ມເຕີມ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ກຳລັງໂຫຼດຄຳແນະນຳ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ປິດເຊດຊັນມີເດຍນີ້"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ຜິດພາດ, ກໍາລັງລອງໃໝ່…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ລຶບອຸປະກອນອອກແລ້ວ"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"ບໍ່ສາມາດໃຊ້ການຄວບຄຸມໄດ້"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"ບໍ່ສາມາດເຂົ້າເຖິງ <xliff:g id="DEVICE">%1$s</xliff:g> ໄດ້. ກະລຸນາກວດສອບແອັບ <xliff:g id="APPLICATION">%2$s</xliff:g> ເພື່ອເບິ່ງວ່າຍັງສາມາດໃຊ້ການຄວບຄຸມໄດ້ຫຼືບໍ່ ແລະ ຍັງບໍ່ໄດ້ປ່ຽນການຕັ້ງຄ່າແອັບເທື່ອ."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ເປີດແອັບ"</string>
<string name="controls_error_generic" msgid="352500456918362905">"ບໍ່ສາມາດໂຫຼດສະຖານະໄດ້"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ຜິດພາດ, ກະລຸນາລອງໃໝ່"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ກຳລັງດຳເນີນການຢູ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index a090319..ded2dd3 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Perbraukite, kad peržiūrėtumėte daugiau"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Įkeliamos rekomendacijos"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Uždaryti šį medijos seansą"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Klaida, bandoma iš naujo…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Įrenginys pašalintas"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Nepavyko įkelti būsenos"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Klaida, bandykite dar kartą"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Vyksta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index f107de9c..c8aa4f0 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1068,9 +1068,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Velciet, lai skatītu citus vienumus"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Notiek ieteikumu ielāde"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Aizvērt multivides sesiju"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Radās kļūda. Mēģina vēlreiz…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Ierīce ir noņemta."</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Nevar ielādēt statusu."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Radās kļūda. Mēģiniet vēlreiz."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Sākta"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0361eed..d251a70 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Повлечете за да видите повеќе"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Затвори ја аудиовизуелнава сесија"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка, повторен обид…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Уредот е отстранет"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Не може да се вчита статусот"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Грешка, обидете се повторно"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Во тек"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 5c80eb3..6aac5bfc 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"കൂടുതൽ കാണാൻ സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ഈ മീഡിയ സെഷൻ അടയ്ക്കുക"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"പിശക്, വീണ്ടും ശ്രമിക്കുന്നു…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ഉപകരണം നീക്കം ചെയ്തു"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"നിയന്ത്രണം ലഭ്യമല്ല"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ആക്സസ് ചെയ്യാനായില്ല. നിയന്ത്രണം ഇപ്പോഴും ലഭ്യമാണെന്നും ആപ്പ് ക്രമീകരണം മാറ്റിയിട്ടില്ലെന്നും ഉറപ്പാക്കാൻ <xliff:g id="APPLICATION">%2$s</xliff:g> ആപ്പ് പരിശോധിക്കുക."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ആപ്പ് തുറക്കുക"</string>
<string name="controls_error_generic" msgid="352500456918362905">"നില ലോഡ് ചെയ്യാനാകുന്നില്ല"</string>
<string name="controls_error_failed" msgid="960228639198558525">"പിശക്, വീണ്ടും ശ്രമിക്കുക"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"പുരോഗതിയിലാണ്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f04df52..ed396ec 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Илүү ихийг харахын тулд шударна уу"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Зөвлөмжүүдийг ачаалж байна"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Медианы энэ харилцан үйлдлийг хаах"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Алдаа, дахин оролдож байна…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Төхөөрөмжийг хассан"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Статус ачаалах боломжгүй"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Алдаа гарав, дахин оролдоно уу"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Үргэлжилж байна"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 8994141..4f63c1d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"अधिक पाहण्यासाठी स्वाइप करा"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"शिफारशी लोड करत आहे"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"हे मीडिया सेशन बंद करा"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"एरर, पुन्हा प्रयत्न करत आहे…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"डिव्हाइस काढून टाकले आहे"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> अॅक्सेस करता आले नाही. नियंत्रण अजूनही उपलब्ध असल्याची आणि ॲपची सेटिंग्ज बदलली नसल्याची खात्री करण्यासाठी <xliff:g id="APPLICATION">%2$s</xliff:g> ॲप तपासा."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"अॅप उघडा"</string>
<string name="controls_error_generic" msgid="352500456918362905">"स्थिती लोड करू शकत नाही"</string>
<string name="controls_error_failed" msgid="960228639198558525">"एरर, पुन्हा प्रयत्न करा"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"प्रगतीपथावर आहे"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index a251c3d..4118ca5 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Leret untuk melihat selanjutnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuatkan cadangan"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Tutup sesi media ini"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ralat, mencuba semula…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Peranti dialih keluar"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Tidak dapat memuatkan status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ralat, cuba lagi"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Sedang berlangsung"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 810388d..5a9e599 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ပိုမိုကြည့်ရှုရန် ပွတ်ဆွဲပါ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ဤမီဒီယာစက်ရှင်ကို ပိတ်ပါ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"မှားသွားသည်၊ ပြန်စမ်းနေသည်…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"စက်ကို ဖယ်ရှားထားသည်"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"အခြေအနေကို ဖွင့်၍မရပါ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"မှားသွားသည်၊ ပြန်စမ်းကြည့်ပါ"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ဆောင်ရွက်နေသည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b208cf2..8930f517 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Sveip for å se flere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laster inn anbefalinger"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Lukk denne medieøkten"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Feil. Prøver igjen …"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Enheten er fjernet"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Kan ikke laste inn status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"En feil oppsto. Prøv på nytt"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Pågår"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index abfb4c8..800f354 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"थप हेर्न स्वाइप गर्नुहोस्"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"यो मिडिया सत्र बन्द गर्नुहोस्"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"त्रुटि भयो, फेरि प्रयास गर्दै…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"यन्त्र हटाइयो"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"नियन्त्रण सुविधा उपलब्ध छैन"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> माथि पहुँच राख्न सकिएन। यो नियन्त्रण सुविधा अझै पनि उपलब्ध छ र <xliff:g id="APPLICATION">%2$s</xliff:g> एपका सेटिङ परिवर्तन गरिएका छैनन् भन्ने कुरा सुनिश्चित गर्न यो एप जाँच्नुहोस्।"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"एप खोल्नुहोस्"</string>
<string name="controls_error_generic" msgid="352500456918362905">"वस्तुस्थिति लोड गर्न सकिएन"</string>
<string name="controls_error_failed" msgid="960228639198558525">"त्रुटि भयो, फेरि प्रयास गर्नु…"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"कार्य हुँदै छ"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index f578c2d..c709a16 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe om meer te zien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Aanbevelingen laden"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Deze mediasessie sluiten"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout. Opnieuw proberen…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Apparaat verwijderd"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Kan status niet laden"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer het opnieuw"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Bezig"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 27a04dd..c0e9f5b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ଅଧିକ ଦେଖିବାକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ଏହି ମିଡିଆ ସେସନ୍ ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ତ୍ରୁଟି, ପୁଣି ଚେଷ୍ଟା କରୁଛି…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ଡିଭାଇସ୍ କାଢ଼ି ଦିଆଯାଇଛି"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳୁ ନାହିଁ"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>କୁ ଆକ୍ସେସ୍ କରିହେଲା ନାହିଁ। ନିୟନ୍ତ୍ରଣ ଏବେ ବି ଉପଲବ୍ଧ ଅଛି ଏବଂ ଆପ୍ ସେଟିଂସ୍ ବଦଳାଯାଇ ନାହିଁ ବୋଲି ସୁନିଶ୍ଚିତ କରିବାକୁ <xliff:g id="APPLICATION">%2$s</xliff:g> ଆପ୍ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ଆପ୍ ଖୋଲନ୍ତୁ"</string>
<string name="controls_error_generic" msgid="352500456918362905">"ସ୍ଥିତି ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ପ୍ରଗତିରେ ଅଛି"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index b8bf05b..0f0a762 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ਇਸ ਮੀਡੀਆ ਸੈਸ਼ਨ ਨੂੰ ਬੰਦ ਕਰੋ"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ਗੜਬੜ, ਮੁੜ ਕੋਸ਼ਿਸ਼ ਹੋ ਰਹੀ ਹੈ…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"ਡੀਵਾਈਸ ਹਟਾਇਆ ਗਿਆ"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ। ਇਹ ਪੱਕਾ ਕਰਨ ਲਈ <xliff:g id="APPLICATION">%2$s</xliff:g> ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ ਕਿ ਕੰਟਰੋਲ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੈ ਅਤੇ ਐਪ ਸੈਟਿੰਗ ਬਦਲੀ ਨਹੀਂ ਹੈ।"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ਐਪ ਖੋਲ੍ਹੋ"</string>
<string name="controls_error_generic" msgid="352500456918362905">"ਸਥਿਤੀ ਲੋਡ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ਗੜਬੜ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ਜਾਰੀ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 8b56f8d..6785efd 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Przesuń palcem, by zobaczyć więcej"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zamknij tę sesję multimediów"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Błąd, próbuję jeszcze raz…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Usunięto urządzenie"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Nie udało się wczytać stanu"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Błąd, spróbuj ponownie"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"W toku"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 5a2005e..d4de51c 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Encerrar esta sessão de mídia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispositivo removido"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Falha ao carregar o status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Em andamento"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index dec586e..344f3c5 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize rapidamente para ver mais."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Fechar esta sessão multimédia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. A tentar novamente…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispositivo removido."</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Impossível carregar o estado."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Em curso"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 5a2005e..d4de51c 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Encerrar esta sessão de mídia"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispositivo removido"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Falha ao carregar o status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Em andamento"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ee844d0..1ad5a37 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1068,9 +1068,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Glisați pentru a vedea mai multe"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Se încarcă recomandările"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Închideți această sesiune media"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Eroare, se încearcă din nou…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Dispozitivul a fost eliminat"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Starea nu se poate încărca"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Eroare, încercați din nou"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"În curs"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 902d948..a8e0a25 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Проведите по экрану, чтобы увидеть больше"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Закрыть этот мультимедийный сеанс"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ошибка. Повторная попытка…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Устройство удалено."</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Не удалось загрузить статус."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ошибка. Повторите попытку."</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Выполняется"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c49843c..859a3f7 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"තව බැලීමට ස්වයිප් කරන්න"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"නිර්දේශ පූරණය කරමින්"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"මෙම මාධ්ය සැසිය වසන්න"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"දෝෂයකි, නැවත උත්සාහ කරමින්…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"උපාංගය ඉවත් කර ඇත"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> වෙත ප්රවේශ විය නොහැකි විය. පාලනය තිබෙන බව සහ යෙදුම් සැකසීම් වෙනස් වී ඇති බව සහතික කර ගැනීමට <xliff:g id="APPLICATION">%2$s</xliff:g> යෙදුම පරීක්ෂා කරන්න."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"යෙදුම විවෘත කරන්න"</string>
<string name="controls_error_generic" msgid="352500456918362905">"තත්ත්වය පූරණය කළ නොහැකිය"</string>
<string name="controls_error_failed" msgid="960228639198558525">"දෝෂයකි, නැවත උත්සාහ කරන්න"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"ප්රගතියේ පවතී"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 920fdd1..bc19338 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Potiahnutím zobrazíte ďalšie položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zavrieť túto reláciu média"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba, skúša sa znova…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Zariadenie je odstránené"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Stav sa nepodarilo načítať"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Chyba, skúste to znova"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Prebieha"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 0b6d3a7..95415d4 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1074,9 +1074,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Če si želite ogledati več, povlecite"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Zapri to sejo predstavnosti"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Napaka, vnovični poskus …"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Naprava je bila odstranjena"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Ni bilo mogoče dostopiti do: <xliff:g id="DEVICE">%1$s</xliff:g>. Preverite aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g> in se prepričajte, da je kontrolnik še vedno na voljo ter da se nastavitve aplikacije niso spremenile."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Odpri aplikacijo"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Stanja ni mogoče naložiti"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Napaka, poskusite znova"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"V teku"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a514750..2152b38 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Rrëshqit shpejt për të shikuar më shumë"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Po ngarkon rekomandimet"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Mbyll këtë sesion të medias"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Gabim, po provohet përsëri"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Pajisja u hoq"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolli është i padisponueshëm"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Nuk mundi të qasej te <xliff:g id="DEVICE">%1$s</xliff:g>. Kontrollo aplikacionin <xliff:g id="APPLICATION">%2$s</xliff:g> për t\'u siguruar që kontrolli të jetë ende i disponueshëm dhe që cilësimet e aplikacionit të mos kenë ndryshuar."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Hap aplikacionin"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Statusi nuk mund të ngarkohet"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Gabim, provo sërish"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Në vazhdim"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 7855ec1..424c546 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1068,9 +1068,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Затворите ову сесију медија"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка, покушава се поново…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Уређај је уклоњен"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Учитавање статуса није успело"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Грешка. Пробајте поново"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"У току"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e6fb28e..f6f9821 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Svep om du vill se mer"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Stäng den här sessionen"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fel, försöker igen …"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Enheten har tagits bort"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Ingen status lästes in"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Fel, försök igen"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Pågår"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index c7962f9..eff31b0 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Funga kipindi hiki cha maudhui"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hitilafu, inajaribu tena…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Kifaa kimeondolewa"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Imeshindwa kupakia hali"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Hitilafu, jaribu tena"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Inaendelea"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index edd8bde..c71839b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"மேலும் பார்க்க ஸ்வைப் செய்யவும்"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"பரிந்துரைகளை ஏற்றுகிறது"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"இந்த மீடியா அமர்வை மூடுக"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"பிழை, மீண்டும் முயல்கிறது…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"சாதனம் அகற்றப்பட்டது"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"நிலையைக் காட்ட முடியவில்லை"</string>
<string name="controls_error_failed" msgid="960228639198558525">"பிழை, மீண்டும் முயலவும்"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"செயல்பாட்டிலுள்ளது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a08d0d4..07bde57 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ఈ మీడియా సెషన్ని మూసివేయండి"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"లోపం, మళ్లీ ప్రయత్నిస్తోంది..."</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"పరికరం తీసివేయబడింది"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"స్థితిని లోడ్ చేయడం సాధ్యపడదు"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"పురోగతిలో ఉంది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 5638f2a51..404f4a4 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"เลื่อนเพื่อดูเพิ่มเติม"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"กำลังโหลดคำแนะนำ"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"ปิดเซสชันสื่อนี้"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"มีข้อผิดพลาด กำลังลองอีกครั้ง…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"นำอุปกรณ์ออกแล้ว"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"โหลดสถานะไม่ได้"</string>
<string name="controls_error_failed" msgid="960228639198558525">"พบข้อผิดพลาด โปรดลองอีกครั้ง"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"กำลังดำเนินการ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index b9b379c..d289933 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Mag-swipe para tumingin ng higit pa"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nilo-load ang rekomendasyon"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Isara ang session ng media na ito"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Nagka-error, sinusubukan ulit…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Inalis ang device"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Hindi ma-load ang status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Nagka-error, subukan ulit"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Isinasagawa"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 48268e7..66cacc1 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Diğer öğeleri görmek için hızlıca kaydırın"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Öneriler yükleniyor"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Bu medya oturumunu kapat"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hata, yeniden deneniyor…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Cihaz kaldırıldı"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Durum yüklenemiyor"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Hata, yeniden deneyin"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Devam ediyor"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 38a478c..c77ecea 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1074,9 +1074,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Гортайте, щоб переглянути інші"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Закрити цей сеанс медіа"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Помилка. Повторна спроба…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Пристрій вилучено"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Не вдалося завантажити статус"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Помилка. Спробуйте знову"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Виконується"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ac99a7b..9ee66ce 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1065,9 +1065,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"اس میڈیا سیشن کو بند کریں"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خرابی، دوبارہ کوشش کی جا رہی ہے…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"آلہ ہٹا دیا گیا"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> تک رسائی حاصل نہیں ہو سکی۔ اس بات کو یقینی بنانے کے لیے کہ کنٹرول ابھی بھی دستیاب ہے اور ایپ کی ترتیبات تبدیل نہیں ہوئی، تو <xliff:g id="APPLICATION">%2$s</xliff:g> ایپ چیک کریں۔"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"ایپ کھولیں"</string>
<string name="controls_error_generic" msgid="352500456918362905">"صورتحال لوڈ نہیں ہو سکتی"</string>
<string name="controls_error_failed" msgid="960228639198558525">"خرابی، دوبارہ کوشش کریں"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"پیشرفت میں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 518f60c..557f2b8 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1062,9 +1062,13 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Batafsil axborot olish uchun suring"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Bu media seansni yopish"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xato, qayta urinilmoqda…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Qurilma olib tashlandi"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Boshqarish imkonsiz"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ochilmadi. <xliff:g id="APPLICATION">%2$s</xliff:g> ilovasining sozlamalari oʻzgarmaganini va hali ham boshqarishga ruxsat borligini tekshiring."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Ilovani ochish"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Holat axboroti yuklanmadi"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Xato, qayta urining"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Bajarilmoqda"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 00e0cf7..c227c5f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Vuốt để xem thêm"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Đóng phiên đa phương tiện này"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Lỗi, đang thử lại…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Đã xóa thiết bị"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Không tải được trạng thái"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Lỗi, hãy thử lại"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Đang thực hiện"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 2664830..bd2ffa6 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑动可查看更多结构"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在加载推荐内容"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"关闭此媒体会话"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"出现错误,正在重试…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"设备已移除"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"无法加载状态"</string>
<string name="controls_error_failed" msgid="960228639198558525">"出现错误,请重试"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"正在进行"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 34b7690..9fdc4ac 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動以查看更多"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"關閉此媒體版面"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"繼續"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"已移除裝置"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"無法載入狀態"</string>
<string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請再試一次"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"進行中"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 5f3911a..5dc9da1 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動即可查看其他結構"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"關閉這個媒體工作階段"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"裝置已遭到移除"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"無法載入狀態"</string>
<string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請再試一次"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"進行中"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9b56c20..da90373 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1062,9 +1062,17 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swayipha ukuze ubone okuningi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ilayisha izincomo"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"Vala leseshini yemidiya"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Iphutha, iyazama futhi…"</string>
- <string name="controls_error_removed" msgid="6299213591234723805">"Idivayisi isusiwe"</string>
+ <!-- no translation found for controls_error_removed (6675638069846014366) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_title (1207794911208047818) -->
+ <skip />
+ <!-- no translation found for controls_error_removed_message (2885911717034750542) -->
+ <skip />
+ <!-- no translation found for controls_open_app (483650971094300141) -->
+ <skip />
<string name="controls_error_generic" msgid="352500456918362905">"Ayikwazi ukulayisha isimo"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Iphutha, zama futhi"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Iyaqhubeka"</string>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0314fc8..820615a6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2641,7 +2641,7 @@
<!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
<string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
<!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=20] -->
- <string name="bubble_dismiss_text">Dismiss</string>
+ <string name="bubble_dismiss_text">Dismiss bubble</string>
<!-- Button text to stop a conversation from bubbling [CHAR LIMIT=60]-->
<string name="bubbles_dont_bubble_conversation">Don\u2019t bubble conversation</string>
<!-- Title text for the bubbles feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=60]-->
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 1dd6409..dbe5a77 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -34,6 +34,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -632,6 +633,7 @@
windowFlags,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+ lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
lp.setTitle("BiometricPrompt");
lp.token = windowToken;
return lp;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index b4937e8..cf793f0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -1156,6 +1156,8 @@
@Override
public void applyUpdate(BubbleData.Update update) {
+ ensureStackViewCreated();
+
// Lazy load overflow bubbles from disk
loadOverflowBubblesFromDisk();
// Update bubbles in overflow.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 790d6a2..c3dcc0b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -264,7 +264,8 @@
mSettingsIcon = findViewById(R.id.settings_button);
mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */,
- true /* singleTaskInstance */);
+ true /* singleTaskInstance */, false /* usePublicVirtualDisplay*/,
+ true /* disableSurfaceViewBackgroundLayer */);
// Set ActivityView's alpha value as zero, since there is no view content to be shown.
setContentVisibility(false);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index 3e694b9..b4672c1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -75,6 +75,20 @@
}
return false;
}
+
+ @Override
+ public int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
+ RecyclerView.State state) {
+ int bubbleCount = state.getItemCount();
+ int columnCount = super.getColumnCountForAccessibility(recycler, state);
+ if (bubbleCount < columnCount) {
+ // If there are 4 columns and bubbles <= 3,
+ // TalkBack says "AppName 1 of 4 in list 4 items"
+ // This is a workaround until TalkBack bug is fixed for GridLayoutManager
+ return bubbleCount;
+ }
+ return columnCount;
+ }
}
@Inject
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 9e7cf1a..353367e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -87,9 +87,7 @@
deviceType: Int
): KClass<out Behavior> {
return when {
- status == Control.STATUS_UNKNOWN -> StatusBehavior::class
- status == Control.STATUS_ERROR -> StatusBehavior::class
- status == Control.STATUS_NOT_FOUND -> StatusBehavior::class
+ status != Control.STATUS_OK -> StatusBehavior::class
deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class
template is ToggleTemplate -> ToggleBehavior::class
template is StatelessTemplate -> TouchBehavior::class
@@ -123,7 +121,11 @@
private val onDialogCancel: () -> Unit = { lastChallengeDialog = null }
val deviceType: Int
- get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType
+ get() = cws.control?.let { it.deviceType } ?: cws.ci.deviceType
+ val controlStatus: Int
+ get() = cws.control?.let { it.status } ?: Control.STATUS_UNKNOWN
+ val controlTemplate: ControlTemplate
+ get() = cws.control?.let { it.controlTemplate } ?: ControlTemplate.NO_TEMPLATE
init {
val ld = layout.getBackground() as LayerDrawable
@@ -140,14 +142,16 @@
cancelUpdate?.run()
- val (controlStatus, template) = cws.control?.let {
- title.setText(it.getTitle())
- subtitle.setText(it.getSubtitle())
- Pair(it.status, it.controlTemplate)
- } ?: run {
+ // For the following statuses only, assume the title/subtitle could not be set properly
+ // by the app and instead use the last known information from favorites
+ if (controlStatus == Control.STATUS_UNKNOWN || controlStatus == Control.STATUS_NOT_FOUND) {
title.setText(cws.ci.controlTitle)
subtitle.setText(cws.ci.controlSubtitle)
- Pair(Control.STATUS_UNKNOWN, ControlTemplate.NO_TEMPLATE)
+ } else {
+ cws.control?.let {
+ title.setText(it.title)
+ subtitle.setText(it.subtitle)
+ }
}
cws.control?.let {
@@ -161,7 +165,8 @@
}
isLoading = false
- behavior = bindBehavior(behavior, findBehaviorClass(controlStatus, template, deviceType))
+ behavior = bindBehavior(behavior,
+ findBehaviorClass(controlStatus, controlTemplate, deviceType))
updateContentDescription()
}
@@ -256,7 +261,13 @@
}
internal fun applyRenderInfo(enabled: Boolean, offset: Int, animated: Boolean = true) {
- val ri = RenderInfo.lookup(context, cws.componentName, deviceType, offset)
+ val deviceTypeOrError = if (controlStatus == Control.STATUS_OK ||
+ controlStatus == Control.STATUS_UNKNOWN) {
+ deviceType
+ } else {
+ RenderInfo.ERROR_ICON
+ }
+ val ri = RenderInfo.lookup(context, cws.componentName, deviceTypeOrError, offset)
val fg = context.resources.getColorStateList(ri.foreground, context.theme)
val newText = nextStatusText
nextStatusText = ""
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
index 09d41bd..3f17a4f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
@@ -35,6 +35,7 @@
) {
companion object {
const val APP_ICON_ID = -1
+ const val ERROR_ICON = -1000
private val iconMap = SparseArray<Drawable>()
private val appIconMap = ArrayMap<ComponentName, Drawable>()
@@ -156,7 +157,8 @@
DeviceTypes.TYPE_CURTAIN to R.drawable.ic_device_blinds,
DeviceTypes.TYPE_DOOR to R.drawable.ic_device_door,
DeviceTypes.TYPE_SHUTTER to R.drawable.ic_device_window,
- DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat
+ DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat,
+ RenderInfo.ERROR_ICON to R.drawable.ic_error_outline
).withDefault {
R.drawable.ic_device_unknown
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index 6bf1897..dac5537 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -19,6 +19,7 @@
import android.app.AlertDialog
import android.app.PendingIntent
import android.content.DialogInterface
+import android.content.Intent
import android.content.pm.PackageManager
import android.service.controls.Control
import android.view.View
@@ -74,6 +75,7 @@
DialogInterface.OnClickListener { dialog, _ ->
try {
cws.control?.getAppIntent()?.send()
+ context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
} catch (e: PendingIntent.CanceledException) {
cvh.setTransientStatus(
cvh.context.resources.getString(R.string.controls_error_failed))
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 5e5ebe9..bc95a25 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -779,7 +779,8 @@
@VisibleForTesting
protected final class PowerOptionsAction extends SinglePressAction {
private PowerOptionsAction() {
- super(R.drawable.ic_lock_power_off, R.string.global_action_power_options);
+ super(com.android.systemui.R.drawable.ic_settings_power,
+ R.string.global_action_power_options);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 1ddb1f5..3cc9127 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -30,6 +30,7 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.drawable.TransitionDrawable;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
@@ -76,6 +77,9 @@
public class PipTouchHandler {
private static final String TAG = "PipTouchHandler";
+ /** Duration of the dismiss scrim fading in/out. */
+ private static final int DISMISS_TRANSITION_DURATION_MS = 200;
+
// Allow dragging the PIP to a location to close it
private final boolean mEnableDismissDragToEdge;
// Allow PIP to resize to a slightly bigger state upon touch
@@ -249,6 +253,8 @@
mTargetView = new DismissCircleView(context);
mTargetViewContainer = new FrameLayout(context);
+ mTargetViewContainer.setBackgroundDrawable(
+ context.getDrawable(R.drawable.floating_dismiss_gradient_transition));
mTargetViewContainer.setClipChildren(false);
mTargetViewContainer.addView(mTargetView);
@@ -553,6 +559,9 @@
mMagneticTargetAnimator
.spring(DynamicAnimation.TRANSLATION_Y, 0f, mTargetSpringConfig)
.start();
+
+ ((TransitionDrawable) mTargetViewContainer.getBackground()).startTransition(
+ DISMISS_TRANSITION_DURATION_MS);
}
}
@@ -565,6 +574,9 @@
mTargetSpringConfig)
.withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE))
.start();
+
+ ((TransitionDrawable) mTargetViewContainer.getBackground()).reverseTransition(
+ DISMISS_TRANSITION_DURATION_MS);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index d7dd6f2..32ef063 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -22,6 +22,7 @@
import android.util.Log;
import android.widget.Switch;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
@@ -41,14 +42,16 @@
private ActivityStarter mActivityStarter;
private long mMillisUntilFinished = 0;
private Callback mCallback = new Callback();
+ private UiEventLogger mUiEventLogger;
@Inject
public ScreenRecordTile(QSHost host, RecordingController controller,
- ActivityStarter activityStarter) {
+ ActivityStarter activityStarter, UiEventLogger uiEventLogger) {
super(host);
mController = controller;
mController.observe(this, mCallback);
mActivityStarter = activityStarter;
+ mUiEventLogger = uiEventLogger;
}
@Override
@@ -112,7 +115,6 @@
}
private void startCountdown() {
- Log.d(TAG, "Starting countdown");
// Close QS, otherwise the permission dialog appears beneath it
getHost().collapsePanels();
Intent intent = mController.getPromptIntent();
@@ -125,7 +127,6 @@
}
private void stopRecording() {
- Log.d(TAG, "Stopping recording from tile");
mController.stopRecording();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index aa63b40..6a8c6149 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -95,14 +95,11 @@
mAvatar.setDrawableWithBadge(picture, userId);
}
- public void setAvatarEnabled(boolean enabled) {
- mAvatar.setEnabled(enabled);
- }
-
public void setDisabledByAdmin(boolean disabled) {
- mRestrictedPadlock.setVisibility(disabled ? View.VISIBLE : View.GONE);
- mName.setEnabled(!disabled);
- mAvatar.setEnabled(!disabled);
+ if (mRestrictedPadlock != null) {
+ mRestrictedPadlock.setVisibility(disabled ? View.VISIBLE : View.GONE);
+ }
+ setEnabled(!disabled);
}
public void setEnabled(boolean enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 89ce125..fba7a22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -16,8 +16,12 @@
package com.android.systemui.qs.tiles;
+import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
+import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;
+
import android.content.Context;
import android.content.Intent;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
@@ -94,18 +98,21 @@
}
String name = getName(mContext, item);
if (item.picture == null) {
- v.bind(name, getDrawable(mContext, item), item.resolveId());
+ v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
} else {
- v.bind(name, item.picture, item.info.id);
+ Drawable drawable = new BitmapDrawable(v.getResources(), item.picture);
+ drawable.setColorFilter(
+ item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
+ v.bind(name, drawable, item.info.id);
}
v.setActivated(item.isCurrent);
+ v.setDisabledByAdmin(item.isDisabledByAdmin);
+ v.setEnabled(item.isSwitchToEnabled);
+ v.setAlpha(v.isEnabled() ? USER_SWITCH_ENABLED_ALPHA : USER_SWITCH_DISABLED_ALPHA);
+
if (item.isCurrent) {
mCurrentUserView = v;
}
- v.setDisabledByAdmin(item.isDisabledByAdmin);
- if (!item.isSwitchToEnabled) {
- v.setEnabled(false);
- }
v.setTag(item);
return v;
}
@@ -113,8 +120,14 @@
private static Drawable getDrawable(Context context,
UserSwitcherController.UserRecord item) {
Drawable icon = getIconDrawable(context, item);
- int iconColorRes = item.isCurrent ? R.color.qs_user_switcher_selected_avatar_icon_color
- : R.color.qs_user_switcher_avatar_icon_color;
+ int iconColorRes;
+ if (item.isCurrent) {
+ iconColorRes = R.color.qs_user_switcher_selected_avatar_icon_color;
+ } else if (!item.isSwitchToEnabled) {
+ iconColorRes = R.color.GM2_grey_600;
+ } else {
+ iconColorRes = R.color.qs_user_switcher_avatar_icon_color;
+ }
icon.setTint(context.getResources().getColor(iconColorRes, context.getTheme()));
int bgRes = item.isCurrent ? R.drawable.bg_avatar_selected : R.drawable.qs_bg_avatar;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index baa2dfd..8a012b8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -577,10 +577,6 @@
// Listen for nav bar mode changes
mNavBarMode = navModeController.addListener(this);
- // Listen for device provisioned/user setup
- updateEnabledState();
- startTracking();
-
// Listen for launcher package changes
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
@@ -601,6 +597,13 @@
.commitUpdate(mContext.getDisplayId());
}
});
+
+ // Listen for user setup
+ startTracking();
+
+ // Connect to the service
+ updateEnabledState();
+ startConnectionToCurrentUser();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java b/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java
new file mode 100644
index 0000000..9dede48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java
@@ -0,0 +1,45 @@
+/*
+ * 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.screenrecord;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+/**
+ * Events related to the SystemUI screen recorder
+ */
+public class Events {
+
+ public enum ScreenRecordEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Screen recording was started")
+ SCREEN_RECORD_START(299),
+ @UiEvent(doc = "Screen recording was stopped from the quick settings tile")
+ SCREEN_RECORD_END_QS_TILE(300),
+ @UiEvent(doc = "Screen recording was stopped from the notification")
+ SCREEN_RECORD_END_NOTIFICATION(301);
+
+ private final int mId;
+ ScreenRecordEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 2ddd6aa..f2e8599 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -36,6 +36,8 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.LongRunning;
@@ -63,22 +65,28 @@
private static final String ACTION_START = "com.android.systemui.screenrecord.START";
private static final String ACTION_STOP = "com.android.systemui.screenrecord.STOP";
+ private static final String ACTION_STOP_NOTIF =
+ "com.android.systemui.screenrecord.STOP_FROM_NOTIF";
private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE";
private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE";
private final RecordingController mController;
- private Notification.Builder mRecordingNotificationBuilder;
private ScreenRecordingAudioSource mAudioSource;
private boolean mShowTaps;
private boolean mOriginalShowTaps;
private ScreenMediaRecorder mRecorder;
private final Executor mLongExecutor;
+ private final UiEventLogger mUiEventLogger;
+ private final NotificationManager mNotificationManager;
@Inject
- public RecordingService(RecordingController controller, @LongRunning Executor executor) {
+ public RecordingService(RecordingController controller, @LongRunning Executor executor,
+ UiEventLogger uiEventLogger, NotificationManager notificationManager) {
mController = controller;
mLongExecutor = executor;
+ mUiEventLogger = uiEventLogger;
+ mNotificationManager = notificationManager;
}
/**
@@ -110,9 +118,6 @@
String action = intent.getAction();
Log.d(TAG, "onStartCommand " + action);
- NotificationManager notificationManager =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-
switch (action) {
case ACTION_START:
mAudioSource = ScreenRecordingAudioSource
@@ -135,10 +140,16 @@
startRecording();
break;
+ case ACTION_STOP_NOTIF:
case ACTION_STOP:
+ // only difference for actions is the log event
+ if (ACTION_STOP_NOTIF.equals(action)) {
+ mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION);
+ } else {
+ mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE);
+ }
stopRecording();
- notificationManager.cancel(NOTIFICATION_RECORDING_ID);
- saveRecording(notificationManager);
+ mNotificationManager.cancel(NOTIFICATION_RECORDING_ID);
stopSelf();
break;
@@ -154,7 +165,7 @@
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
// Remove notification
- notificationManager.cancel(NOTIFICATION_VIEW_ID);
+ mNotificationManager.cancel(NOTIFICATION_VIEW_ID);
startActivity(Intent.createChooser(shareIntent, shareLabel)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
@@ -173,7 +184,7 @@
Toast.LENGTH_LONG).show();
// Remove notification
- notificationManager.cancel(NOTIFICATION_VIEW_ID);
+ mNotificationManager.cancel(NOTIFICATION_VIEW_ID);
Log.d(TAG, "Deleted recording " + uri);
break;
}
@@ -190,14 +201,20 @@
super.onCreate();
}
+ @VisibleForTesting
+ protected ScreenMediaRecorder getRecorder() {
+ return mRecorder;
+ }
+
/**
* Begin the recording session
*/
private void startRecording() {
try {
- mRecorder.start();
+ getRecorder().start();
mController.updateState(true);
createRecordingNotification();
+ mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START);
} catch (IOException | RemoteException e) {
Toast.makeText(this,
R.string.screenrecord_start_error, Toast.LENGTH_LONG)
@@ -206,7 +223,8 @@
}
}
- private void createRecordingNotification() {
+ @VisibleForTesting
+ protected void createRecordingNotification() {
Resources res = getResources();
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
@@ -214,9 +232,7 @@
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(getString(R.string.screenrecord_channel_description));
channel.enableVibration(true);
- NotificationManager notificationManager =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel);
Bundle extras = new Bundle();
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
@@ -226,7 +242,9 @@
? res.getString(R.string.screenrecord_ongoing_screen_only)
: res.getString(R.string.screenrecord_ongoing_screen_and_audio);
- mRecordingNotificationBuilder = new Notification.Builder(this, CHANNEL_ID)
+
+ Intent stopIntent = getNotificationIntent(this);
+ Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_screenrecord)
.setContentTitle(notificationTitle)
.setContentText(getResources().getString(R.string.screenrecord_stop_text))
@@ -235,17 +253,28 @@
.setColor(getResources().getColor(R.color.GM2_red_700))
.setOngoing(true)
.setContentIntent(
- PendingIntent.getService(
- this, REQUEST_CODE, getStopIntent(this),
+ PendingIntent.getService(this, REQUEST_CODE, stopIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
.addExtras(extras);
- notificationManager.notify(NOTIFICATION_RECORDING_ID,
- mRecordingNotificationBuilder.build());
- Notification notification = mRecordingNotificationBuilder.build();
- startForeground(NOTIFICATION_RECORDING_ID, notification);
+ startForeground(NOTIFICATION_RECORDING_ID, builder.build());
}
- private Notification createSaveNotification(ScreenMediaRecorder.SavedRecording recording) {
+ @VisibleForTesting
+ protected Notification createProcessingNotification() {
+ Resources res = getApplicationContext().getResources();
+ String notificationTitle = mAudioSource == ScreenRecordingAudioSource.NONE
+ ? res.getString(R.string.screenrecord_ongoing_screen_only)
+ : res.getString(R.string.screenrecord_ongoing_screen_and_audio);
+ Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
+ .setContentTitle(notificationTitle)
+ .setContentText(
+ getResources().getString(R.string.screenrecord_background_processing_label))
+ .setSmallIcon(R.drawable.ic_screenrecord);
+ return builder.build();
+ }
+
+ @VisibleForTesting
+ protected Notification createSaveNotification(ScreenMediaRecorder.SavedRecording recording) {
Uri uri = recording.getUri();
Intent viewIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION)
@@ -301,44 +330,39 @@
private void stopRecording() {
setTapsVisible(mOriginalShowTaps);
- mRecorder.end();
+ if (getRecorder() != null) {
+ getRecorder().end();
+ saveRecording();
+ } else {
+ Log.e(TAG, "stopRecording called, but recorder was null");
+ }
mController.updateState(false);
}
- private void saveRecording(NotificationManager notificationManager) {
- Resources res = getApplicationContext().getResources();
- String notificationTitle = mAudioSource == ScreenRecordingAudioSource.NONE
- ? res.getString(R.string.screenrecord_ongoing_screen_only)
- : res.getString(R.string.screenrecord_ongoing_screen_and_audio);
- Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
- .setContentTitle(notificationTitle)
- .setContentText(
- getResources().getString(R.string.screenrecord_background_processing_label))
- .setSmallIcon(R.drawable.ic_screenrecord);
- notificationManager.notify(NOTIFICATION_PROCESSING_ID, builder.build());
+ private void saveRecording() {
+ mNotificationManager.notify(NOTIFICATION_PROCESSING_ID, createProcessingNotification());
mLongExecutor.execute(() -> {
try {
Log.d(TAG, "saving recording");
- Notification notification = createSaveNotification(mRecorder.save());
+ Notification notification = createSaveNotification(getRecorder().save());
if (!mController.isRecording()) {
Log.d(TAG, "showing saved notification");
- notificationManager.notify(NOTIFICATION_VIEW_ID, notification);
+ mNotificationManager.notify(NOTIFICATION_VIEW_ID, notification);
}
} catch (IOException e) {
Log.e(TAG, "Error saving screen recording: " + e.getMessage());
Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG)
.show();
} finally {
- notificationManager.cancel(NOTIFICATION_PROCESSING_ID);
+ mNotificationManager.cancel(NOTIFICATION_PROCESSING_ID);
}
});
}
private void setTapsVisible(boolean turnOn) {
int value = turnOn ? 1 : 0;
- Settings.System.putInt(getApplicationContext().getContentResolver(),
- Settings.System.SHOW_TOUCHES, value);
+ Settings.System.putInt(getContentResolver(), Settings.System.SHOW_TOUCHES, value);
}
/**
@@ -350,6 +374,15 @@
return new Intent(context, RecordingService.class).setAction(ACTION_STOP);
}
+ /**
+ * Get the recording notification content intent
+ * @param context
+ * @return
+ */
+ protected static Intent getNotificationIntent(Context context) {
+ return new Intent(context, RecordingService.class).setAction(ACTION_STOP_NOTIF);
+ }
+
private static Intent getShareIntent(Context context, String path) {
return new Intent(context, RecordingService.class).setAction(ACTION_SHARE)
.putExtra(EXTRA_PATH, path);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index a8c0324..5bee9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -60,7 +60,11 @@
private final Handler mHandler;
- /** Re-usable map of top-level notifications to their sorted children if any.*/
+ /**
+ * Re-usable map of top-level notifications to their sorted children if any.
+ * If the top-level notification doesn't have children, its key will still exist in this map
+ * with its value explicitly set to null.
+ */
private final HashMap<NotificationEntry, List<NotificationEntry>> mTmpChildOrderMap =
new HashMap<>();
@@ -212,10 +216,19 @@
}
orderedChildren.add(ent);
} else {
- // Top-level notif
- mTmpChildOrderMap.put(ent, null);
+ // Top-level notif (either a summary or single notification)
+
+ // A child may have already added its summary to mTmpChildOrderMap with a
+ // list of children. This can happen since there's no guarantee summaries are
+ // sorted before its children.
+ if (!mTmpChildOrderMap.containsKey(ent)) {
+ // mTmpChildOrderMap's keyset is used to iterate through all entries, so it's
+ // necessary to add each top-level notif as a key
+ mTmpChildOrderMap.put(ent, null);
+ }
toShow.add(ent.getRow());
}
+
}
ArrayList<ExpandableNotificationRow> viewsToRemove = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
index df3609b..1c076c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
@@ -23,6 +23,9 @@
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -36,10 +39,14 @@
@Singleton
public class HighPriorityProvider {
private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
+ private final NotificationGroupManager mGroupManager;
@Inject
- public HighPriorityProvider(PeopleNotificationIdentifier peopleNotificationIdentifier) {
+ public HighPriorityProvider(
+ PeopleNotificationIdentifier peopleNotificationIdentifier,
+ NotificationGroupManager groupManager) {
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
+ mGroupManager = groupManager;
}
/**
@@ -74,13 +81,25 @@
private boolean hasHighPriorityChild(ListEntry entry) {
+ List<NotificationEntry> children = null;
+
if (entry instanceof GroupEntry) {
- for (NotificationEntry child : ((GroupEntry) entry).getChildren()) {
+ // New notification pipeline
+ children = ((GroupEntry) entry).getChildren();
+ } else if (entry.getRepresentativeEntry() != null
+ && mGroupManager.isGroupSummary(entry.getRepresentativeEntry().getSbn())) {
+ // Old notification pipeline
+ children = mGroupManager.getChildren(entry.getRepresentativeEntry().getSbn());
+ }
+
+ if (children != null) {
+ for (NotificationEntry child : children) {
if (isHighPriority(child)) {
return true;
}
}
}
+
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index df3748a..512d0f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -16,11 +16,15 @@
package com.android.systemui.statusbar.policy;
+import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
+import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.database.DataSetObserver;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
@@ -46,8 +50,6 @@
private static final String TAG = "KeyguardUserSwitcher";
private static final boolean ALWAYS_ON = false;
- private static final float USER_SWITCH_ENABLED_ALPHA = 1.0f;
- private static final float USER_SWITCH_DISABLED_ALPHA = 0.38f;
private final Container mUserSwitcherContainer;
private final KeyguardStatusBarView mStatusBarView;
@@ -286,27 +288,34 @@
if (item.picture == null) {
v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
} else {
- v.bind(name, item.picture, item.info.id);
+ Drawable drawable = new BitmapDrawable(v.getResources(), item.picture);
+ drawable.setColorFilter(
+ item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
+ v.bind(name, drawable, item.info.id);
}
- // Disable the icon if switching is disabled
- v.setAvatarEnabled(item.isSwitchToEnabled);
- convertView.setActivated(item.isCurrent);
+ v.setActivated(item.isCurrent);
+ v.setDisabledByAdmin(item.isDisabledByAdmin);
+ v.setEnabled(item.isSwitchToEnabled);
+ v.setAlpha(v.isEnabled() ? USER_SWITCH_ENABLED_ALPHA : USER_SWITCH_DISABLED_ALPHA);
+
if (item.isCurrent) {
- mCurrentUserView = convertView;
+ mCurrentUserView = v;
}
- convertView.setTag(item);
- convertView.setAlpha(
- item.isCurrent || item.isSwitchToEnabled ? USER_SWITCH_ENABLED_ALPHA
- : USER_SWITCH_DISABLED_ALPHA);
- convertView.setEnabled(item.isSwitchToEnabled);
- return convertView;
+ v.setTag(item);
+ return v;
}
private static Drawable getDrawable(Context context,
UserSwitcherController.UserRecord item) {
Drawable drawable = getIconDrawable(context, item);
- int iconColorRes = item.isCurrent ? R.color.kg_user_switcher_selected_avatar_icon_color
- : R.color.kg_user_switcher_avatar_icon_color;
+ int iconColorRes;
+ if (item.isCurrent) {
+ iconColorRes = R.color.kg_user_switcher_selected_avatar_icon_color;
+ } else if (!item.isSwitchToEnabled) {
+ iconColorRes = R.color.GM2_grey_600;
+ } else {
+ iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
+ }
drawable.setTint(context.getResources().getColor(iconColorRes, context.getTheme()));
if (item.isCurrent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index db00770..270f248 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -31,6 +31,9 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
@@ -81,6 +84,9 @@
@Singleton
public class UserSwitcherController implements Dumpable {
+ public static final float USER_SWITCH_ENABLED_ALPHA = 1.0f;
+ public static final float USER_SWITCH_DISABLED_ALPHA = 0.38f;
+
private static final String TAG = "UserSwitcherController";
private static final boolean DEBUG = false;
private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING =
@@ -674,6 +680,12 @@
}
}
+ protected static ColorFilter getDisabledUserAvatarColorFilter() {
+ ColorMatrix matrix = new ColorMatrix();
+ matrix.setSaturation(0f); // 0 - grayscale
+ return new ColorMatrixColorFilter(matrix);
+ }
+
protected static Drawable getIconDrawable(Context context, UserRecord item) {
int iconRes;
if (item.isAddUser) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
index e905e67..da7953d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
@@ -245,9 +245,6 @@
*/
var hapticsEnabled = true
- /** Whether the HAPTIC_FEEDBACK_ENABLED setting is true. */
- private var systemHapticsEnabled = false
-
/** Default spring configuration to use for animating the object into a target. */
var springConfig = PhysicsAnimator.SpringConfig(
SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_NO_BOUNCY)
@@ -259,24 +256,7 @@
var flungIntoTargetSpringConfig = springConfig
init {
- val hapticSettingObserver =
- object : ContentObserver(Handler.getMain()) {
- override fun onChange(selfChange: Boolean) {
- systemHapticsEnabled =
- Settings.System.getIntForUser(
- context.contentResolver,
- Settings.System.HAPTIC_FEEDBACK_ENABLED,
- 0,
- UserHandle.USER_CURRENT) != 0
- }
- }
-
- context.contentResolver.registerContentObserver(
- Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED),
- true /* notifyForDescendants */, hapticSettingObserver)
-
- // Trigger the observer once to initialize systemHapticsEnabled.
- hapticSettingObserver.onChange(false /* selfChange */)
+ initHapticSettingObserver(context)
}
/**
@@ -623,6 +603,43 @@
companion object {
/**
+ * Whether the HAPTIC_FEEDBACK_ENABLED setting is true.
+ *
+ * We put it in the companion object because we need to register a settings observer and
+ * [MagnetizedObject] doesn't have an obvious lifecycle so we don't have a good time to
+ * remove that observer. Since this settings is shared among all instances we just let all
+ * instances read from this value.
+ */
+ private var systemHapticsEnabled = false
+ private var hapticSettingObserverInitialized = false
+
+ private fun initHapticSettingObserver(context: Context) {
+ if (hapticSettingObserverInitialized) {
+ return
+ }
+
+ val hapticSettingObserver =
+ object : ContentObserver(Handler.getMain()) {
+ override fun onChange(selfChange: Boolean) {
+ systemHapticsEnabled =
+ Settings.System.getIntForUser(
+ context.contentResolver,
+ Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ 0,
+ UserHandle.USER_CURRENT) != 0
+ }
+ }
+
+ context.contentResolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED),
+ true /* notifyForDescendants */, hapticSettingObserver)
+
+ // Trigger the observer once to initialize systemHapticsEnabled.
+ hapticSettingObserver.onChange(false /* selfChange */)
+ hapticSettingObserverInitialized = true
+ }
+
+ /**
* Magnetizes the given view. Magnetized views are attracted to one or more magnetic
* targets. Magnetic targets attract objects that are dragged near them, and hold them there
* unless they're moved away or released. Releasing objects inside a magnetic target
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index 74d0610..29d7a52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -45,6 +45,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -210,6 +211,14 @@
assertTrue((layoutParams.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0);
}
+ @Test
+ public void testLayoutParams_excludesImeInsets() {
+ final IBinder windowToken = mock(IBinder.class);
+ final WindowManager.LayoutParams layoutParams =
+ AuthContainerView.getLayoutParams(windowToken);
+ assertTrue((layoutParams.getFitInsetsTypes() & WindowInsets.Type.ime()) == 0);
+ }
+
private void initializeContainer(int authenticators) {
AuthContainerView.Config config = new AuthContainerView.Config();
config.mContext = mContext;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 8a8d227..e502459 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -29,6 +29,7 @@
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -53,6 +54,8 @@
private ActivityStarter mActivityStarter;
@Mock
private QSTileHost mHost;
+ @Mock
+ private UiEventLogger mUiEventLogger;
private TestableLooper mTestableLooper;
private ScreenRecordTile mTile;
@@ -68,7 +71,7 @@
when(mHost.getContext()).thenReturn(mContext);
- mTile = new ScreenRecordTile(mHost, mController, mActivityStarter);
+ mTile = new ScreenRecordTile(mHost, mController, mActivityStarter, mUiEventLogger);
}
// Test that the tile is inactive and labeled correctly when the controller is neither starting
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
new file mode 100644
index 0000000..283a47c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.screenrecord;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class RecordingServiceTest extends SysuiTestCase {
+
+ @Mock
+ private UiEventLogger mUiEventLogger;
+ @Mock
+ private RecordingController mController;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ScreenMediaRecorder mScreenMediaRecorder;
+ @Mock
+ private Notification mNotification;
+ @Mock
+ private Executor mExecutor;
+
+ private RecordingService mRecordingService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mUiEventLogger,
+ mNotificationManager));
+
+ // Return actual context info
+ doReturn(mContext).when(mRecordingService).getApplicationContext();
+ doReturn(mContext.getUserId()).when(mRecordingService).getUserId();
+ doReturn(mContext.getPackageName()).when(mRecordingService).getPackageName();
+ doReturn(mContext.getContentResolver()).when(mRecordingService).getContentResolver();
+
+ // Mock notifications
+ doNothing().when(mRecordingService).createRecordingNotification();
+ doReturn(mNotification).when(mRecordingService).createProcessingNotification();
+ doReturn(mNotification).when(mRecordingService).createSaveNotification(any());
+
+ doNothing().when(mRecordingService).startForeground(anyInt(), any());
+ doReturn(mScreenMediaRecorder).when(mRecordingService).getRecorder();
+ }
+
+ @Test
+ public void testLogStartRecording() {
+ Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false);
+ mRecordingService.onStartCommand(startIntent, 0, 0);
+
+ verify(mUiEventLogger, times(1)).log(Events.ScreenRecordEvent.SCREEN_RECORD_START);
+ }
+
+ @Test
+ public void testLogStopFromQsTile() {
+ Intent stopIntent = RecordingService.getStopIntent(mContext);
+ mRecordingService.onStartCommand(stopIntent, 0, 0);
+
+ // Verify that we log the correct event
+ verify(mUiEventLogger, times(1)).log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE);
+ verify(mUiEventLogger, times(0))
+ .log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION);
+ }
+
+ @Test
+ public void testLogStopFromNotificationIntent() {
+ Intent stopIntent = RecordingService.getNotificationIntent(mContext);
+ mRecordingService.onStartCommand(stopIntent, 0, 0);
+
+ // Verify that we log the correct event
+ verify(mUiEventLogger, times(1))
+ .log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION);
+ verify(mUiEventLogger, times(0)).log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 78e9b33..2b12c22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
@@ -38,6 +38,7 @@
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
import org.junit.Before;
import org.junit.Test;
@@ -45,16 +46,22 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.Arrays;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class HighPriorityProviderTest extends SysuiTestCase {
@Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
+ @Mock private NotificationGroupManager mGroupManager;
private HighPriorityProvider mHighPriorityProvider;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mHighPriorityProvider = new HighPriorityProvider(mPeopleNotificationIdentifier);
+ mHighPriorityProvider = new HighPriorityProvider(
+ mPeopleNotificationIdentifier,
+ mGroupManager);
}
@Test
@@ -166,6 +173,22 @@
}
@Test
+ public void testIsHighPriority_checkChildrenToCalculatePriority() {
+ // GIVEN: a summary with low priority has a highPriorityChild and a lowPriorityChild
+ final NotificationEntry summary = createNotifEntry(false);
+ final NotificationEntry lowPriorityChild = createNotifEntry(false);
+ final NotificationEntry highPriorityChild = createNotifEntry(true);
+ when(mGroupManager.isGroupSummary(summary.getSbn())).thenReturn(true);
+ when(mGroupManager.getChildren(summary.getSbn())).thenReturn(
+ new ArrayList<>(Arrays.asList(lowPriorityChild, highPriorityChild)));
+
+ // THEN the summary is high priority since it has a high priority child
+ assertTrue(mHighPriorityProvider.isHighPriority(summary));
+ }
+
+ // Tests below here are only relevant to the NEW notification pipeline which uses GroupEntry
+
+ @Test
public void testIsHighPriority_summaryUpdated() {
// GIVEN a GroupEntry with a lowPrioritySummary and no children
final GroupEntry parentEntry = new GroupEntry("test_group_key");
@@ -186,7 +209,7 @@
}
@Test
- public void testIsHighPriority_checkChildrenToCalculatePriority() {
+ public void testIsHighPriority_checkChildrenToCalculatePriorityOf() {
// GIVEN:
// GroupEntry = parentEntry, summary = lowPrioritySummary
// NotificationEntry = lowPriorityChild
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 1c47131..82a7774 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
@@ -77,7 +77,8 @@
mock(NotificationEntryManagerLogger::class.java),
sectionsManager,
personNotificationIdentifier,
- HighPriorityProvider(personNotificationIdentifier)
+ HighPriorityProvider(personNotificationIdentifier,
+ mock(NotificationGroupManager::class.java))
)
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 8eb401a..1ce3dfe 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -157,7 +157,6 @@
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.pm.Installer;
-import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.storage.AppFuseBridge;
import com.android.server.storage.StorageSessionController;
import com.android.server.storage.StorageSessionController.ExternalStorageServiceException;
@@ -3343,15 +3342,23 @@
public void fixupAppDir(String path) {
final Matcher matcher = KNOWN_APP_DIR_PATHS.matcher(path);
if (matcher.matches()) {
- AndroidPackage pkg = mPmInternal.getPackage(matcher.group(3));
- if (pkg != null) {
+ if (matcher.group(2) == null) {
+ Log.e(TAG, "Asked to fixup an app dir without a userId: " + path);
+ return;
+ }
+ try {
+ int userId = Integer.parseInt(matcher.group(2));
+ String packageName = matcher.group(3);
+ int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, userId);
try {
- mVold.fixupAppDir(path + "/", pkg.getUid());
+ mVold.fixupAppDir(path + "/", uid);
} catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Failed to fixup app dir for " + pkg.getPackageName(), e);
+ Log.e(TAG, "Failed to fixup app dir for " + packageName, e);
}
- } else {
- Log.e(TAG, "Can't find package belonging to " + path);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Invalid userId in path: " + path, e);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Couldn't find package to fixup app dir " + path, e);
}
} else {
Log.e(TAG, "Path " + path + " is not a valid application-specific directory");
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 9f2a77c..2e62864 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2214,11 +2214,11 @@
app.setHasForegroundActivities(true);
}
- final Map<String, Pair<String, Long>> pkgDataInfoMap;
- final Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
+ Map<String, Pair<String, Long>> pkgDataInfoMap;
+ Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
boolean bindMountAppStorageDirs = false;
boolean bindMountAppsData = mAppDataIsolationEnabled
- && UserHandle.isApp(app.uid)
+ && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid))
&& mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
// Get all packages belongs to the same shared uid. sharedPackages is empty array
@@ -2266,6 +2266,13 @@
}
}
+ // If it's an isolated process, it should not even mount its own app data directories,
+ // since it has no access to them anyway.
+ if (app.isolated) {
+ pkgDataInfoMap = null;
+ whitelistedAppDataInfoMap = null;
+ }
+
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
@@ -2276,13 +2283,14 @@
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
+ // We can't isolate app data and storage data as parent zygote already did that.
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
- bindMountAppsData, bindMountAppStorageDirs,
+ false, false,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 5c6b481..45f95fd 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -38,6 +38,7 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Log;
import android.util.PrintWriterPrinter;
@@ -329,11 +330,13 @@
final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
suppressNoisyIntent, a2dpVolume);
+ final String name = TextUtils.emptyIfNull(device.getName());
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + MediaMetrics.SEPARATOR
+ "postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent")
.set(MediaMetrics.Property.STATE, state == BluetoothProfile.STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.set(MediaMetrics.Property.INDEX, a2dpVolume)
+ .set(MediaMetrics.Property.NAME, name)
.record();
// operations of removing and posting messages related to A2DP device state change must be
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 27d9ba0..6d45aba 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1893,7 +1893,7 @@
Binder.getCallingUid(), true, keyEventMode);
break;
case KeyEvent.KEYCODE_VOLUME_MUTE:
- if (event.getRepeatCount() == 0) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
Binder.getCallingUid(), true, VOL_ADJUST_NORMAL);
@@ -2155,7 +2155,8 @@
}
int oldIndex = mStreamStates[streamType].getIndex(device);
- if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
+ if (adjustVolume
+ && (direction != AudioManager.ADJUST_SAME) && (keyEventMode != VOL_ADJUST_END)) {
mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
if (isMuteAdjust) {
@@ -2238,6 +2239,11 @@
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
}
+ }
+
+ final int newIndex = mStreamStates[streamType].getIndex(device);
+
+ if (adjustVolume) {
synchronized (mHdmiClientLock) {
if (mHdmiManager != null) {
// mHdmiCecSink true => mHdmiPlaybackClient != null
@@ -2290,8 +2296,7 @@
}
}
}
- int index = mStreamStates[streamType].getIndex(device);
- sendVolumeUpdate(streamType, oldIndex, index, flags, device);
+ sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
}
// Called after a delay when volume down is pressed while muted
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 694f0d6..13b6c7c 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -500,6 +500,22 @@
static final String PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_AND_SEND_ACTIVE_SOURCE =
"wake_up_and_send_active_source";
+ /**
+ * Property to decide the device behaviour when <Active Source> is lost.
+ *
+ * <p>This property applies to playback devices.
+ * <p>Possible values are:
+ * <ul>
+ * <li><b>none</b> No power state change (default).
+ * <li><b>standby_now</b> PowerManager.goToSleep() is called.
+ * </ul>
+ */
+ static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST =
+ "ro.hdmi.cec.source.power_state_change_on_active_source_lost";
+
+ static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE = "none";
+ static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW = "standby_now";
+
static final int RECORDING_TYPE_DIGITAL_RF = 1;
static final int RECORDING_TYPE_ANALOGUE_RF = 2;
static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index d5168ac..ef27810 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -67,6 +67,10 @@
@VisibleForTesting
protected String mPlaybackDeviceActionOnRoutingControl;
+ // Behaviour of the device when <Active Source> is lost in favor of another device.
+ @VisibleForTesting
+ protected String mPowerStateChangeOnActiveSourceLost;
+
HdmiCecLocalDevicePlayback(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);
@@ -79,6 +83,10 @@
mPlaybackDeviceActionOnRoutingControl = SystemProperties.get(
Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL,
Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE);
+
+ mPowerStateChangeOnActiveSourceLost = SystemProperties.get(
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
}
@Override
@@ -240,6 +248,28 @@
return !getWakeLock().isHeld();
}
+ @Override
+ @ServiceThreadOnly
+ protected boolean handleActiveSource(HdmiCecMessage message) {
+ super.handleActiveSource(message);
+ if (mIsActiveSource) {
+ return true;
+ }
+ switch (mPowerStateChangeOnActiveSourceLost) {
+ case Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW:
+ mService.standby();
+ return true;
+ case Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE:
+ return true;
+ default:
+ Slog.w(TAG, "Invalid property '"
+ + Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
+ + "' value: "
+ + mPowerStateChangeOnActiveSourceLost);
+ return true;
+ }
+ }
+
@ServiceThreadOnly
protected boolean handleUserControlPressed(HdmiCecMessage message) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 3a29622..176ec3f 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.PendingIntent;
import android.media.session.ISessionManager;
import android.media.session.MediaSession;
import android.os.Binder;
@@ -76,6 +77,9 @@
/**
* Implement this to customize the logic for which MediaSession should consume which key event.
*
+ * Note: This session will have greater priority over the {@link PendingIntent} returned from
+ * {@link #getMediaButtonReceiver(KeyEvent, int, boolean)}.
+ *
* @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons.
* @param uid the uid value retrieved by calling {@link Binder#getCallingUid()} from
* {@link ISessionManager#dispatchMediaKeyEvent(String, boolean, KeyEvent, boolean)}
@@ -84,7 +88,27 @@
* @return a {@link MediaSession.Token} instance that should consume the given key event.
*/
@Nullable
- MediaSession.Token getSessionForKeyEvent(@NonNull KeyEvent keyEvent, int uid,
+ MediaSession.Token getMediaSession(@NonNull KeyEvent keyEvent, int uid,
+ boolean asSystemService) {
+ return null;
+ }
+
+ /**
+ * Implement this to customize the logic for which MediaButtonReceiver should consume a
+ * dispatched key event.
+ *
+ * Note: This pending intent will have lower priority over the {@link MediaSession.Token}
+ * returned from {@link #getMediaSession(KeyEvent, int, boolean)}.
+ *
+ * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons.
+ * @param uid the uid value retrieved by calling {@link Binder#getCallingUid()} from
+ * {@link ISessionManager#dispatchMediaKeyEvent(String, boolean, KeyEvent, boolean)}
+ * @param asSystemService {@code true} if the event came from the system service via hardware
+ * devices. {@code false} if the event came from the app process through key injection.
+ * @return a {@link PendingIntent} instance that should receive the dispatched key event.
+ */
+ @Nullable
+ PendingIntent getMediaButtonReceiver(@NonNull KeyEvent keyEvent, int uid,
boolean asSystemService) {
return null;
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 75a89a2..0e99715 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -584,7 +584,7 @@
mAllRouterRecords.put(binder, routerRecord);
userRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyRoutesToRouter,
+ obtainMessage(UserHandler::notifyRouterRegistered,
userRecord.mHandler, routerRecord));
}
@@ -1769,8 +1769,8 @@
}
}
- private void notifyRoutesToRouter(@NonNull RouterRecord routerRecord) {
- List<MediaRoute2Info> routes = new ArrayList<>();
+ private void notifyRouterRegistered(@NonNull RouterRecord routerRecord) {
+ List<MediaRoute2Info> currentRoutes = new ArrayList<>();
MediaRoute2ProviderInfo systemProviderInfo = null;
for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) {
@@ -1780,27 +1780,32 @@
systemProviderInfo = providerInfo;
continue;
}
- routes.addAll(providerInfo.getRoutes());
+ currentRoutes.addAll(providerInfo.getRoutes());
}
+ RoutingSessionInfo currentSystemSessionInfo;
if (routerRecord.mHasModifyAudioRoutingPermission) {
if (systemProviderInfo != null) {
- routes.addAll(systemProviderInfo.getRoutes());
+ currentRoutes.addAll(systemProviderInfo.getRoutes());
} else {
// This shouldn't happen.
Slog.w(TAG, "notifyRoutesToRouter: System route provider not found.");
}
+ currentSystemSessionInfo = mSystemProvider.getSessionInfos().get(0);
} else {
- routes.add(mSystemProvider.getDefaultRoute());
+ currentRoutes.add(mSystemProvider.getDefaultRoute());
+ currentSystemSessionInfo = mSystemProvider.getDefaultSessionInfo();
}
- if (routes.size() == 0) {
+ if (currentRoutes.size() == 0) {
return;
}
+
try {
- routerRecord.mRouter.notifyRoutesAdded(routes);
+ routerRecord.mRouter.notifyRouterRegistered(
+ currentRoutes, currentSystemSessionInfo);
} catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify all routes. Router probably died.", ex);
+ Slog.w(TAG, "Failed to notify router registered. Router probably died.", ex);
}
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index f360a4a..afae20d 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -2404,18 +2404,32 @@
return;
}
MediaSessionRecord session = null;
+ MediaButtonReceiverHolder mediaButtonReceiverHolder = null;
- // Retrieve custom session for key event if it exists.
if (mCustomMediaKeyDispatcher != null) {
- MediaSession.Token token = mCustomMediaKeyDispatcher.getSessionForKeyEvent(
- keyEvent, uid, asSystemService);
+ MediaSession.Token token = mCustomMediaKeyDispatcher.getMediaSession(keyEvent, uid,
+ asSystemService);
if (token != null) {
session = getMediaSessionRecordLocked(token);
}
+
+ if (session == null) {
+ PendingIntent pi = mCustomMediaKeyDispatcher.getMediaButtonReceiver(keyEvent,
+ uid, asSystemService);
+ if (pi != null) {
+ mediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext,
+ mCurrentFullUserRecord.mFullUserId, pi);
+ }
+ }
}
- if (session == null) {
+ if (session == null && mediaButtonReceiverHolder == null) {
session = (MediaSessionRecord) mCurrentFullUserRecord.getMediaButtonSessionLocked();
+
+ if (session == null) {
+ mediaButtonReceiverHolder =
+ mCurrentFullUserRecord.mLastMediaButtonReceiverHolder;
+ }
}
if (session != null) {
@@ -2438,16 +2452,12 @@
} catch (RemoteException e) {
Log.w(TAG, "Failed to send callback", e);
}
- } else if (mCurrentFullUserRecord.mLastMediaButtonReceiverHolder != null) {
+ } else if (mediaButtonReceiverHolder != null) {
if (needWakeLock) {
mKeyEventReceiver.acquireWakeLockLocked();
}
String callingPackageName =
(asSystemService) ? mContext.getPackageName() : packageName;
-
- MediaButtonReceiverHolder mediaButtonReceiverHolder =
- mCurrentFullUserRecord.mLastMediaButtonReceiverHolder;
-
boolean sent = mediaButtonReceiverHolder.send(
mContext, keyEvent, callingPackageName,
needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, mKeyEventReceiver,
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index e846daf..0ec4b39 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -108,7 +108,7 @@
public void init() {
synchronized (mLock) {
try {
- if (!mHistoryDir.mkdir()) {
+ if (!mHistoryDir.exists() && !mHistoryDir.mkdir()) {
throw new IllegalStateException("could not create history directory");
}
mVersionFile.createNewFile();
@@ -197,7 +197,7 @@
readLocked(
file, notifications, new NotificationHistoryFilter.Builder().build());
} catch (Exception e) {
- Slog.e(TAG, "error reading " + file.getBaseFile().getName(), e);
+ Slog.e(TAG, "error reading " + file.getBaseFile().getAbsolutePath(), e);
}
}
@@ -223,7 +223,7 @@
break;
}
} catch (Exception e) {
- Slog.e(TAG, "error reading " + file.getBaseFile().getName(), e);
+ Slog.e(TAG, "error reading " + file.getBaseFile().getAbsolutePath(), e);
}
}
@@ -279,7 +279,7 @@
}
file.delete();
// TODO: delete all relevant bitmaps, once they exist
- mHistoryFiles.removeLast();
+ mHistoryFiles.remove(file);
}
private void scheduleDeletion(File file, long creationTime, int retentionDays) {
@@ -317,11 +317,17 @@
private static void readLocked(AtomicFile file, NotificationHistory notificationsOut,
NotificationHistoryFilter filter) throws IOException {
- try (FileInputStream in = file.openRead()) {
+ FileInputStream in = null;
+ try {
+ in = file.openRead();
NotificationHistoryProtoHelper.read(in, notificationsOut, filter);
} catch (FileNotFoundException e) {
- Slog.e(TAG, "Cannot file " + file.getBaseFile().getName(), e);
+ Slog.e(TAG, "Cannot open " + file.getBaseFile().getAbsolutePath(), e);
throw e;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
}
}
@@ -334,9 +340,15 @@
}
if (ACTION_HISTORY_DELETION.equals(action)) {
try {
- final String filePath = intent.getStringExtra(EXTRA_KEY);
- AtomicFile fileToDelete = new AtomicFile(new File(filePath));
- fileToDelete.delete();
+ synchronized (mLock) {
+ final String filePath = intent.getStringExtra(EXTRA_KEY);
+ AtomicFile fileToDelete = new AtomicFile(new File(filePath));
+ if (DEBUG) {
+ Slog.d(TAG, "Removed " + fileToDelete.getBaseFile().getName());
+ }
+ fileToDelete.delete();
+ mHistoryFiles.remove(fileToDelete);
+ }
} catch (Exception e) {
Slog.e(TAG, "Failed to delete notification history file", e);
}
@@ -345,27 +357,23 @@
};
final class WriteBufferRunnable implements Runnable {
- long currentTime = 0;
- AtomicFile latestNotificationsFile;
@Override
public void run() {
- if (DEBUG) Slog.d(TAG, "WriteBufferRunnable");
+ long time = System.currentTimeMillis();
+ run(time, new AtomicFile(new File(mHistoryDir, String.valueOf(time))));
+ }
+
+ void run(long time, AtomicFile file) {
synchronized (mLock) {
- if (currentTime == 0) {
- currentTime = System.currentTimeMillis();
- }
- if (latestNotificationsFile == null) {
- latestNotificationsFile = new AtomicFile(
- new File(mHistoryDir, String.valueOf(currentTime)));
- }
+ if (DEBUG) Slog.d(TAG, "WriteBufferRunnable "
+ + file.getBaseFile().getAbsolutePath());
try {
- writeLocked(latestNotificationsFile, mBuffer);
- mHistoryFiles.addFirst(latestNotificationsFile);
+ writeLocked(file, mBuffer);
+ mHistoryFiles.addFirst(file);
mBuffer = new NotificationHistory();
- scheduleDeletion(latestNotificationsFile.getBaseFile(), currentTime,
- HISTORY_RETENTION_DAYS);
+ scheduleDeletion(file.getBaseFile(), time, HISTORY_RETENTION_DAYS);
} catch (IOException e) {
Slog.e(TAG, "Failed to write buffer to disk. not flushing buffer", e);
}
@@ -382,7 +390,7 @@
@Override
public void run() {
- if (DEBUG) Slog.d(TAG, "RemovePackageRunnable");
+ if (DEBUG) Slog.d(TAG, "RemovePackageRunnable " + mPkg);
synchronized (mLock) {
// Remove packageName entries from pending history
mBuffer.removeNotificationsFromWrite(mPkg);
@@ -398,7 +406,7 @@
writeLocked(af, notifications);
} catch (Exception e) {
Slog.e(TAG, "Cannot clean up file on pkg removal "
- + af.getBaseFile().getName(), e);
+ + af.getBaseFile().getAbsolutePath(), e);
}
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a95dc30..5585e98 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2672,7 +2672,7 @@
mHistoryManager.addNotification(new HistoricalNotification.Builder()
.setPackage(r.getSbn().getPackageName())
.setUid(r.getSbn().getUid())
- .setUserId(r.getUserId())
+ .setUserId(r.getSbn().getNormalizedUserId())
.setChannelId(r.getChannel().getId())
.setChannelName(r.getChannel().getName().toString())
.setPostedTimeMs(System.currentTimeMillis())
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 766fae6..5e52748 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10713,6 +10713,20 @@
return resultList;
}
+ private int getVendorPartitionVersion() {
+ final String version = SystemProperties.get("ro.vndk.version");
+ if (!version.isEmpty()) {
+ try {
+ return Integer.parseInt(version);
+ } catch (NumberFormatException ignore) {
+ if (ArrayUtils.contains(Build.VERSION.ACTIVE_CODENAMES, version)) {
+ return Build.VERSION_CODES.CUR_DEVELOPMENT;
+ }
+ }
+ }
+ return Build.VERSION_CODES.P;
+ }
+
@GuardedBy({"mInstallLock", "mLock"})
private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
@@ -10894,7 +10908,7 @@
// Scan as privileged apps that share a user with a priv-app.
final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
- && SystemProperties.getInt("ro.vndk.version", 28) < 28;
+ && getVendorPartitionVersion() < 28;
if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
&& !pkg.isPrivileged()
&& (pkg.getSharedUserId() != null)
@@ -12070,6 +12084,20 @@
+ pkg.getPackageName()
+ " is static and cannot be upgraded.");
}
+ } else {
+ if ((scanFlags & SCAN_AS_VENDOR) != 0) {
+ if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) {
+ Slog.w(TAG, "System overlay " + pkg.getPackageName()
+ + " targets an SDK below the required SDK level of vendor"
+ + " overlays (" + getVendorPartitionVersion() + ")."
+ + " This will become an install error in a future release");
+ }
+ } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) {
+ Slog.w(TAG, "System overlay " + pkg.getPackageName()
+ + " targets an SDK below the required SDK level of system"
+ + " overlays (" + Build.VERSION.SDK_INT + ")."
+ + " This will become an install error in a future release");
+ }
}
} else {
// A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index c0c9b32..cc4505c 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -191,7 +191,6 @@
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@@ -257,21 +256,17 @@
@GuardedBy("mNotificationStatsLock")
private INotificationManager mNotificationManagerService;
- private final Object mProcessStatsLock = new Object();
- @GuardedBy("mProcessStatsLock")
+ @GuardedBy("mProcStatsLock")
private IProcessStats mProcessStatsService;
- private final Object mCpuTrackerLock = new Object();
- @GuardedBy("mCpuTrackerLock")
+ @GuardedBy("mProcessCpuTimeLock")
private ProcessCpuTracker mProcessCpuTracker;
- private final Object mDebugElapsedClockLock = new Object();
@GuardedBy("mDebugElapsedClockLock")
private long mDebugElapsedClockPreviousValue = 0;
@GuardedBy("mDebugElapsedClockLock")
private long mDebugElapsedClockPullCount = 0;
- private final Object mDebugFailingElapsedClockLock = new Object();
@GuardedBy("mDebugFailingElapsedClockLock")
private long mDebugFailingElapsedClockPreviousValue = 0;
@GuardedBy("mDebugFailingElapsedClockLock")
@@ -284,26 +279,40 @@
private TelephonyManager mTelephony;
private SubscriptionManager mSubscriptionManager;
+ @GuardedBy("mKernelWakelockLock")
private KernelWakelockReader mKernelWakelockReader;
+ @GuardedBy("mKernelWakelockLock")
private KernelWakelockStats mTmpWakelockStats;
+ @GuardedBy("mDiskIoLock")
private StoragedUidIoStatsReader mStoragedUidIoStatsReader;
+ @GuardedBy("mCpuTimePerFreqLock")
private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
// Disables throttler on CPU time readers.
+ @GuardedBy("mCpuTimePerUidLock")
private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
+ @GuardedBy("mCpuTimePerUidFreqLock")
private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader;
+ @GuardedBy("mCpuActiveTimeLock")
private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader;
+ @GuardedBy("mClusterTimeLock")
private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader;
+ @GuardedBy("mProcStatsLock")
private File mBaseDir;
+ @GuardedBy("mHealthHalLock")
private BatteryService.HealthServiceWrapper mHealthService;
@Nullable
+ @GuardedBy("mCpuTimePerThreadFreqLock")
private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
+ private final Object mBatteryStatsHelperLock = new Object();
+ @GuardedBy("mBatteryStatsHelperLock")
private BatteryStatsHelper mBatteryStatsHelper = null;
+ @GuardedBy("mBatteryStatsHelperLock")
private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS;
private StatsPullAtomCallbackImpl mStatsCallbackImpl;
@@ -311,19 +320,75 @@
private final Object mAppOpsSamplingRateLock = new Object();
@GuardedBy("mAppOpsSamplingRateLock")
private int mAppOpsSamplingRate = 0;
+ private final Object mDangerousAppOpsListLock = new Object();
+ @GuardedBy("mDangerousAppOpsListLock")
private final ArraySet<Integer> mDangerousAppOpsList = new ArraySet<>();
// Baselines that stores list of NetworkStats right after initializing, with associated
- // information. This is used to calculate difference when pulling
- // {Mobile|Wifi}BytesTransfer* atoms. Note that this is not thread-safe, and must
- // only be accessed on the background thread.
+ // information. This is used to calculate difference when pulling BytesTransfer atoms.
@NonNull
- private final List<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>();
+ @GuardedBy("mDataBytesTransferLock")
+ private final ArrayList<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>();
// Listener for monitoring subscriptions changed event.
private StatsSubscriptionsListener mStatsSubscriptionsListener;
// List that stores SubInfo of subscriptions that ever appeared since boot.
- private final CopyOnWriteArrayList<SubInfo> mHistoricalSubs = new CopyOnWriteArrayList<>();
+ @GuardedBy("mDataBytesTransferLock")
+ private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>();
+
+ // Puller locks
+ private final Object mDataBytesTransferLock = new Object();
+ private final Object mBluetoothBytesTransferLock = new Object();
+ private final Object mKernelWakelockLock = new Object();
+ private final Object mCpuTimePerFreqLock = new Object();
+ private final Object mCpuTimePerUidLock = new Object();
+ private final Object mCpuTimePerUidFreqLock = new Object();
+ private final Object mCpuActiveTimeLock = new Object();
+ private final Object mCpuClusterTimeLock = new Object();
+ private final Object mWifiActivityInfoLock = new Object();
+ private final Object mModemActivityInfoLock = new Object();
+ private final Object mBluetoothActivityInfoLock = new Object();
+ private final Object mSystemElapsedRealtimeLock = new Object();
+ private final Object mSystemUptimeLock = new Object();
+ private final Object mProcessMemoryStateLock = new Object();
+ private final Object mProcessMemoryHighWaterMarkLock = new Object();
+ private final Object mProcessMemorySnapshotLock = new Object();
+ private final Object mSystemIonHeapSizeLock = new Object();
+ private final Object mIonHeapSizeLock = new Object();
+ private final Object mProcessSystemIonHeapSizeLock = new Object();
+ private final Object mTemperatureLock = new Object();
+ private final Object mCooldownDeviceLock = new Object();
+ private final Object mBinderCallsStatsLock = new Object();
+ private final Object mBinderCallsStatsExceptionsLock = new Object();
+ private final Object mLooperStatsLock = new Object();
+ private final Object mDiskStatsLock = new Object();
+ private final Object mDirectoryUsageLock = new Object();
+ private final Object mAppSizeLock = new Object();
+ private final Object mCategorySizeLock = new Object();
+ private final Object mNumBiometricsEnrolledLock = new Object();
+ private final Object mProcStatsLock = new Object();
+ private final Object mDiskIoLock = new Object();
+ private final Object mPowerProfileLock = new Object();
+ private final Object mProcessCpuTimeLock = new Object();
+ private final Object mCpuTimePerThreadFreqLock = new Object();
+ private final Object mDeviceCalculatedPowerUseLock = new Object();
+ private final Object mDeviceCalculatedPowerBlameUidLock = new Object();
+ private final Object mDeviceCalculatedPowerBlameOtherLock = new Object();
+ private final Object mDebugElapsedClockLock = new Object();
+ private final Object mDebugFailingElapsedClockLock = new Object();
+ private final Object mBuildInformationLock = new Object();
+ private final Object mRoleHolderLock = new Object();
+ private final Object mTimeZoneDataInfoLock = new Object();
+ private final Object mExternalStorageInfoLock = new Object();
+ private final Object mAppsOnExternalStorageInfoLock = new Object();
+ private final Object mFaceSettingsLock = new Object();
+ private final Object mAppOpsLock = new Object();
+ private final Object mRuntimeAppOpAccessMessageLock = new Object();
+ private final Object mNotificationRemoteViewsLock = new Object();
+ private final Object mDangerousPermissionStateLock = new Object();
+ private final Object mHealthHalLock = new Object();
+ private final Object mAttributedAppOpsLock = new Object();
+ private final Object mSettingsStatsLock = new Object();
public StatsPullAtomService(Context context) {
super(context);
@@ -353,123 +418,229 @@
case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER:
- return pullDataBytesTransfer(atomTag, data);
+ synchronized (mDataBytesTransferLock) {
+ return pullDataBytesTransferLocked(atomTag, data);
+ }
case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
- return pullBluetoothBytesTransfer(atomTag, data);
+ synchronized (mBluetoothBytesTransferLock) {
+ return pullBluetoothBytesTransferLocked(atomTag, data);
+ }
case FrameworkStatsLog.KERNEL_WAKELOCK:
- return pullKernelWakelock(atomTag, data);
+ synchronized (mKernelWakelockLock) {
+ return pullKernelWakelockLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_TIME_PER_FREQ:
- return pullCpuTimePerFreq(atomTag, data);
+ synchronized (mCpuTimePerFreqLock) {
+ return pullCpuTimePerFreqLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_TIME_PER_UID:
- return pullCpuTimePerUid(atomTag, data);
+ synchronized (mCpuTimePerUidLock) {
+ return pullCpuTimePerUidLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
- return pullCpuTimeperUidFreq(atomTag, data);
+ synchronized (mCpuTimePerUidFreqLock) {
+ return pullCpuTimePerUidFreqLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_ACTIVE_TIME:
- return pullCpuActiveTime(atomTag, data);
+ synchronized (mCpuActiveTimeLock) {
+ return pullCpuActiveTimeLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_CLUSTER_TIME:
- return pullCpuClusterTime(atomTag, data);
+ synchronized (mCpuClusterTimeLock) {
+ return pullCpuClusterTimeLocked(atomTag, data);
+ }
case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
- return pullWifiActivityInfo(atomTag, data);
+ synchronized (mWifiActivityInfoLock) {
+ return pullWifiActivityInfoLocked(atomTag, data);
+ }
case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
- return pullModemActivityInfo(atomTag, data);
+ synchronized (mModemActivityInfoLock) {
+ return pullModemActivityInfoLocked(atomTag, data);
+ }
case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
- return pullBluetoothActivityInfo(atomTag, data);
+ synchronized (mBluetoothActivityInfoLock) {
+ return pullBluetoothActivityInfoLocked(atomTag, data);
+ }
case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
- return pullSystemElapsedRealtime(atomTag, data);
+ synchronized (mSystemElapsedRealtimeLock) {
+ return pullSystemElapsedRealtimeLocked(atomTag, data);
+ }
case FrameworkStatsLog.SYSTEM_UPTIME:
- return pullSystemUptime(atomTag, data);
+ synchronized (mSystemUptimeLock) {
+ return pullSystemUptimeLocked(atomTag, data);
+ }
case FrameworkStatsLog.PROCESS_MEMORY_STATE:
- return pullProcessMemoryState(atomTag, data);
+ synchronized (mProcessMemoryStateLock) {
+ return pullProcessMemoryStateLocked(atomTag, data);
+ }
case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
- return pullProcessMemoryHighWaterMark(atomTag, data);
+ synchronized (mProcessMemoryHighWaterMarkLock) {
+ return pullProcessMemoryHighWaterMarkLocked(atomTag, data);
+ }
case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
- return pullProcessMemorySnapshot(atomTag, data);
+ synchronized (mProcessMemorySnapshotLock) {
+ return pullProcessMemorySnapshotLocked(atomTag, data);
+ }
case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
- return pullSystemIonHeapSize(atomTag, data);
+ synchronized (mSystemIonHeapSizeLock) {
+ return pullSystemIonHeapSizeLocked(atomTag, data);
+ }
case FrameworkStatsLog.ION_HEAP_SIZE:
- return pullIonHeapSize(atomTag, data);
+ synchronized (mIonHeapSizeLock) {
+ return pullIonHeapSizeLocked(atomTag, data);
+ }
case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
- return pullProcessSystemIonHeapSize(atomTag, data);
+ synchronized (mProcessSystemIonHeapSizeLock) {
+ return pullProcessSystemIonHeapSizeLocked(atomTag, data);
+ }
case FrameworkStatsLog.TEMPERATURE:
- return pullTemperature(atomTag, data);
+ synchronized (mTemperatureLock) {
+ return pullTemperatureLocked(atomTag, data);
+ }
case FrameworkStatsLog.COOLING_DEVICE:
- return pullCooldownDevice(atomTag, data);
+ synchronized (mCooldownDeviceLock) {
+ return pullCooldownDeviceLocked(atomTag, data);
+ }
case FrameworkStatsLog.BINDER_CALLS:
- return pullBinderCallsStats(atomTag, data);
+ synchronized (mBinderCallsStatsLock) {
+ return pullBinderCallsStatsLocked(atomTag, data);
+ }
case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
- return pullBinderCallsStatsExceptions(atomTag, data);
+ synchronized (mBinderCallsStatsExceptionsLock) {
+ return pullBinderCallsStatsExceptionsLocked(atomTag, data);
+ }
case FrameworkStatsLog.LOOPER_STATS:
- return pullLooperStats(atomTag, data);
+ synchronized (mLooperStatsLock) {
+ return pullLooperStatsLocked(atomTag, data);
+ }
case FrameworkStatsLog.DISK_STATS:
- return pullDiskStats(atomTag, data);
+ synchronized (mDiskStatsLock) {
+ return pullDiskStatsLocked(atomTag, data);
+ }
case FrameworkStatsLog.DIRECTORY_USAGE:
- return pullDirectoryUsage(atomTag, data);
+ synchronized (mDirectoryUsageLock) {
+ return pullDirectoryUsageLocked(atomTag, data);
+ }
case FrameworkStatsLog.APP_SIZE:
- return pullAppSize(atomTag, data);
+ synchronized (mAppSizeLock) {
+ return pullAppSizeLocked(atomTag, data);
+ }
case FrameworkStatsLog.CATEGORY_SIZE:
- return pullCategorySize(atomTag, data);
+ synchronized (mCategorySizeLock) {
+ return pullCategorySizeLocked(atomTag, data);
+ }
case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
- return pullNumBiometricsEnrolled(
- BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
+ synchronized (mNumBiometricsEnrolledLock) {
+ return pullNumBiometricsEnrolledLocked(
+ BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
+ }
case FrameworkStatsLog.NUM_FACES_ENROLLED:
- return pullNumBiometricsEnrolled(
- BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
+ synchronized (mNumBiometricsEnrolledLock) {
+ return pullNumBiometricsEnrolledLocked(
+ BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
+ }
case FrameworkStatsLog.PROC_STATS:
- return pullProcStats(ProcessStats.REPORT_ALL, atomTag, data);
+ synchronized (mProcStatsLock) {
+ return pullProcStatsLocked(ProcessStats.REPORT_ALL, atomTag, data);
+ }
case FrameworkStatsLog.PROC_STATS_PKG_PROC:
- return pullProcStats(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, data);
+ synchronized (mProcStatsLock) {
+ return pullProcStatsLocked(ProcessStats.REPORT_PKG_PROC_STATS, atomTag,
+ data);
+ }
case FrameworkStatsLog.DISK_IO:
- return pullDiskIO(atomTag, data);
+ synchronized (mDiskIoLock) {
+ return pullDiskIOLocked(atomTag, data);
+ }
case FrameworkStatsLog.POWER_PROFILE:
- return pullPowerProfile(atomTag, data);
+ synchronized (mPowerProfileLock) {
+ return pullPowerProfileLocked(atomTag, data);
+ }
case FrameworkStatsLog.PROCESS_CPU_TIME:
- return pullProcessCpuTime(atomTag, data);
+ synchronized (mProcessCpuTimeLock) {
+ return pullProcessCpuTimeLocked(atomTag, data);
+ }
case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
- return pullCpuTimePerThreadFreq(atomTag, data);
+ synchronized (mCpuTimePerThreadFreqLock) {
+ return pullCpuTimePerThreadFreqLocked(atomTag, data);
+ }
case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
- return pullDeviceCalculatedPowerUse(atomTag, data);
+ synchronized (mDeviceCalculatedPowerUseLock) {
+ return pullDeviceCalculatedPowerUseLocked(atomTag, data);
+ }
case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
- return pullDeviceCalculatedPowerBlameUid(atomTag, data);
+ synchronized (mDeviceCalculatedPowerBlameUidLock) {
+ return pullDeviceCalculatedPowerBlameUidLocked(atomTag, data);
+ }
case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
- return pullDeviceCalculatedPowerBlameOther(atomTag, data);
+ synchronized (mDeviceCalculatedPowerBlameOtherLock) {
+ return pullDeviceCalculatedPowerBlameOtherLocked(atomTag, data);
+ }
case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
- return pullDebugElapsedClock(atomTag, data);
+ synchronized (mDebugElapsedClockLock) {
+ return pullDebugElapsedClockLocked(atomTag, data);
+ }
case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
- return pullDebugFailingElapsedClock(atomTag, data);
+ synchronized (mDebugFailingElapsedClockLock) {
+ return pullDebugFailingElapsedClockLocked(atomTag, data);
+ }
case FrameworkStatsLog.BUILD_INFORMATION:
- return pullBuildInformation(atomTag, data);
+ synchronized (mBuildInformationLock) {
+ return pullBuildInformationLocked(atomTag, data);
+ }
case FrameworkStatsLog.ROLE_HOLDER:
- return pullRoleHolder(atomTag, data);
+ synchronized (mRoleHolderLock) {
+ return pullRoleHolderLocked(atomTag, data);
+ }
case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
- return pullDangerousPermissionState(atomTag, data);
- case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
- return pullTimeZoneDataInfo(atomTag, data);
- case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
- return pullExternalStorageInfo(atomTag, data);
- case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
- return pullAppsOnExternalStorageInfo(atomTag, data);
- case FrameworkStatsLog.FACE_SETTINGS:
- return pullFaceSettings(atomTag, data);
- case FrameworkStatsLog.APP_OPS:
- return pullAppOps(atomTag, data);
- case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
- return pullRuntimeAppOpAccessMessage(atomTag, data);
- case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
- return pullNotificationRemoteViews(atomTag, data);
case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
- return pullDangerousPermissionState(atomTag, data);
+ synchronized (mDangerousPermissionStateLock) {
+ return pullDangerousPermissionStateLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
+ synchronized (mTimeZoneDataInfoLock) {
+ return pullTimeZoneDataInfoLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
+ synchronized (mExternalStorageInfoLock) {
+ return pullExternalStorageInfoLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
+ synchronized (mAppsOnExternalStorageInfoLock) {
+ return pullAppsOnExternalStorageInfoLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.FACE_SETTINGS:
+ synchronized (mFaceSettingsLock) {
+ return pullFaceSettingsLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.APP_OPS:
+ synchronized (mAppOpsLock) {
+ return pullAppOpsLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
+ synchronized (mRuntimeAppOpAccessMessageLock) {
+ return pullRuntimeAppOpAccessMessageLocked(atomTag, data);
+ }
+ case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
+ synchronized (mNotificationRemoteViewsLock) {
+ return pullNotificationRemoteViewsLocked(atomTag, data);
+ }
case FrameworkStatsLog.BATTERY_LEVEL:
case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
case FrameworkStatsLog.BATTERY_VOLTAGE:
case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
- return pullHealthHal(atomTag, data);
+ synchronized (mHealthHalLock) {
+ return pullHealthHalLocked(atomTag, data);
+ }
case FrameworkStatsLog.ATTRIBUTED_APP_OPS:
- return pullAttributedAppOps(atomTag, data);
+ synchronized (mAttributedAppOpsLock) {
+ return pullAttributedAppOpsLocked(atomTag, data);
+ }
case FrameworkStatsLog.SETTING_SNAPSHOT:
- return pullSettingsStats(atomTag, data);
- case FrameworkStatsLog.DISPLAY_WAKE_REASON:
- return pullDisplayWakeStats(atomTag, data);
+ synchronized (mSettingsStatsLock) {
+ return pullSettingsStatsLocked(atomTag, data);
+ }
default:
throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
}
@@ -500,6 +671,8 @@
}
}
+ // We do not hold locks within this function because it is guaranteed to be called before the
+ // pullers are ever run, as the pullers are not yet registered with statsd.
void initializePullersState() {
// Get Context Managers
mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
@@ -515,6 +688,7 @@
// Initialize PROC_STATS
mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull");
+ mBaseDir.mkdirs();
// Disables throttler on CPU time readers.
mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false);
@@ -542,9 +716,6 @@
mKernelCpuThreadReader =
KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
- // Used by PROC_STATS and PROC_STATS_PKG_PROC atoms
- mBaseDir.mkdirs();
-
// Initialize HealthService
mHealthService = new BatteryService.HealthServiceWrapper();
try {
@@ -656,7 +827,6 @@
registerBatteryVoltage();
registerBatteryCycleCount();
registerSettingsStats();
- registerDisplayWakeStats();
}
private void initAndRegisterNetworkStatsPullers() {
@@ -783,7 +953,7 @@
}
private IProcessStats getIProcessStatsService() {
- synchronized (mProcessStatsLock) {
+ synchronized (mProcStatsLock) {
if (mProcessStatsService == null) {
mProcessStatsService = IProcessStats.Stub.asInterface(
ServiceManager.getService(ProcessStats.SERVICE_NAME));
@@ -791,7 +961,7 @@
if (mProcessStatsService != null) {
try {
mProcessStatsService.asBinder().linkToDeath(() -> {
- synchronized (mProcessStatsLock) {
+ synchronized (mProcStatsLock) {
mProcessStatsService = null;
}
}, /* flags */ 0);
@@ -882,8 +1052,7 @@
return ret;
}
- private int pullDataBytesTransfer(
- int atomTag, @NonNull List<StatsEvent> pulledData) {
+ private int pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData) {
final List<NetworkStatsExt> current = collectNetworkStatsSnapshotForAtom(atomTag);
if (current == null) {
@@ -1237,12 +1406,11 @@
return null;
}
- private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
- // TODO: Investigate whether the synchronized keyword is needed.
+ private BluetoothActivityEnergyInfo fetchBluetoothData() {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
- SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
- "bluetooth");
+ SynchronousResultReceiver bluetoothReceiver =
+ new SynchronousResultReceiver("bluetooth");
adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
return awaitControllerInfo(bluetoothReceiver);
} else {
@@ -1251,7 +1419,7 @@
}
}
- int pullBluetoothBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
+ int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info == null || info.getUidTraffic() == null) {
return StatsManager.PULL_SKIP;
@@ -1279,7 +1447,7 @@
);
}
- int pullKernelWakelock(int atomTag, List<StatsEvent> pulledData) {
+ int pullKernelWakelockLocked(int atomTag, List<StatsEvent> pulledData) {
final KernelWakelockStats wakelockStats =
mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
@@ -1310,7 +1478,7 @@
);
}
- int pullCpuTimePerFreq(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuTimePerFreqLocked(int atomTag, List<StatsEvent> pulledData) {
for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
if (clusterTimeMs != null) {
@@ -1341,7 +1509,7 @@
);
}
- int pullCpuTimePerUid(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuTimePerUidLocked(int atomTag, List<StatsEvent> pulledData) {
mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
StatsEvent e = StatsEvent.newBuilder()
@@ -1371,7 +1539,7 @@
);
}
- int pullCpuTimeperUidFreq(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) {
mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
if (cpuFreqTimeMs[freqIndex] != 0) {
@@ -1404,7 +1572,7 @@
);
}
- int pullCpuActiveTime(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuActiveTimeLocked(int atomTag, List<StatsEvent> pulledData) {
mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
@@ -1432,7 +1600,7 @@
);
}
- int pullCpuClusterTime(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuClusterTimeLocked(int atomTag, List<StatsEvent> pulledData) {
mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
for (int i = 0; i < cpuClusterTimesMs.length; i++) {
StatsEvent e = StatsEvent.newBuilder()
@@ -1458,7 +1626,7 @@
);
}
- int pullWifiActivityInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullWifiActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
long token = Binder.clearCallingIdentity();
try {
SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
@@ -1510,7 +1678,7 @@
);
}
- int pullModemActivityInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
long token = Binder.clearCallingIdentity();
try {
SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
@@ -1548,7 +1716,7 @@
);
}
- int pullBluetoothActivityInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullBluetoothActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info == null) {
return StatsManager.PULL_SKIP;
@@ -1580,7 +1748,7 @@
);
}
- int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
+ int pullSystemElapsedRealtimeLocked(int atomTag, List<StatsEvent> pulledData) {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeLong(SystemClock.elapsedRealtime())
@@ -1599,7 +1767,7 @@
);
}
- int pullSystemUptime(int atomTag, List<StatsEvent> pulledData) {
+ int pullSystemUptimeLocked(int atomTag, List<StatsEvent> pulledData) {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeLong(SystemClock.uptimeMillis())
@@ -1621,7 +1789,7 @@
);
}
- int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) {
+ int pullProcessMemoryStateLocked(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> processMemoryStates =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
@@ -1665,7 +1833,7 @@
);
}
- int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) {
+ int pullProcessMemoryHighWaterMarkLocked(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
@@ -1720,7 +1888,7 @@
);
}
- int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
+ int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
@@ -1782,7 +1950,7 @@
);
}
- int pullSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
+ int pullSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
@@ -1805,7 +1973,7 @@
);
}
- int pullIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
+ int pullIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb();
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
@@ -1825,7 +1993,7 @@
);
}
- int pullProcessSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
+ int pullProcessSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
for (IonAllocations allocations : result) {
StatsEvent e = StatsEvent.newBuilder()
@@ -1852,7 +2020,7 @@
);
}
- int pullTemperature(int atomTag, List<StatsEvent> pulledData) {
+ int pullTemperatureLocked(int atomTag, List<StatsEvent> pulledData) {
IThermalService thermalService = getIThermalService();
if (thermalService == null) {
return StatsManager.PULL_SKIP;
@@ -1890,7 +2058,7 @@
);
}
- int pullCooldownDevice(int atomTag, List<StatsEvent> pulledData) {
+ int pullCooldownDeviceLocked(int atomTag, List<StatsEvent> pulledData) {
IThermalService thermalService = getIThermalService();
if (thermalService == null) {
return StatsManager.PULL_SKIP;
@@ -1930,7 +2098,7 @@
);
}
- int pullBinderCallsStats(int atomTag, List<StatsEvent> pulledData) {
+ int pullBinderCallsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
BinderCallsStatsService.Internal binderStats =
LocalServices.getService(BinderCallsStatsService.Internal.class);
if (binderStats == null) {
@@ -1974,7 +2142,7 @@
);
}
- int pullBinderCallsStatsExceptions(int atomTag, List<StatsEvent> pulledData) {
+ int pullBinderCallsStatsExceptionsLocked(int atomTag, List<StatsEvent> pulledData) {
BinderCallsStatsService.Internal binderStats =
LocalServices.getService(BinderCallsStatsService.Internal.class);
if (binderStats == null) {
@@ -2009,7 +2177,7 @@
);
}
- int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
+ int pullLooperStatsLocked(int atomTag, List<StatsEvent> pulledData) {
LooperStats looperStats = LocalServices.getService(LooperStats.class);
if (looperStats == null) {
return StatsManager.PULL_SKIP;
@@ -2052,7 +2220,7 @@
);
}
- int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
+ int pullDiskStatsLocked(int atomTag, List<StatsEvent> pulledData) {
// Run a quick-and-dirty performance test: write 512 bytes
byte[] junk = new byte[512];
for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
@@ -2118,7 +2286,7 @@
);
}
- int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
+ int pullDirectoryUsageLocked(int atomTag, List<StatsEvent> pulledData) {
StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
@@ -2159,7 +2327,7 @@
);
}
- int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
+ int pullAppSizeLocked(int atomTag, List<StatsEvent> pulledData) {
try {
String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
JSONObject json = new JSONObject(jsonStr);
@@ -2203,7 +2371,7 @@
);
}
- int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
+ int pullCategorySizeLocked(int atomTag, List<StatsEvent> pulledData) {
try {
String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
JSONObject json = new JSONObject(jsonStr);
@@ -2317,7 +2485,8 @@
);
}
- private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
+ private int pullNumBiometricsEnrolledLocked(int modality, int atomTag,
+ List<StatsEvent> pulledData) {
final PackageManager pm = mContext.getPackageManager();
FingerprintManager fingerprintManager = null;
FaceManager faceManager = null;
@@ -2385,43 +2554,41 @@
);
}
- private int pullProcStats(int section, int atomTag, List<StatsEvent> pulledData) {
+ private int pullProcStatsLocked(int section, int atomTag, List<StatsEvent> pulledData) {
IProcessStats processStatsService = getIProcessStatsService();
if (processStatsService == null) {
return StatsManager.PULL_SKIP;
}
- synchronized (mProcessStatsLock) {
- final long token = Binder.clearCallingIdentity();
- try {
- // force procstats to flush & combine old files into one store
- long lastHighWaterMark = readProcStatsHighWaterMark(section);
- List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // force procstats to flush & combine old files into one store
+ long lastHighWaterMark = readProcStatsHighWaterMark(section);
+ List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
- ProcessStats procStats = new ProcessStats(false);
- long highWaterMark = processStatsService.getCommittedStatsMerged(
- lastHighWaterMark, section, true, statsFiles, procStats);
+ ProcessStats procStats = new ProcessStats(false);
+ long highWaterMark = processStatsService.getCommittedStatsMerged(
+ lastHighWaterMark, section, true, statsFiles, procStats);
- // aggregate the data together for westworld consumption
- ProtoOutputStream proto = new ProtoOutputStream();
- procStats.dumpAggregatedProtoForStatsd(proto);
+ // aggregate the data together for westworld consumption
+ ProtoOutputStream proto = new ProtoOutputStream();
+ procStats.dumpAggregatedProtoForStatsd(proto);
- StatsEvent e = StatsEvent.newBuilder()
- .setAtomId(atomTag)
- .writeByteArray(proto.getBytes())
- .build();
- pulledData.add(e);
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeByteArray(proto.getBytes())
+ .build();
+ pulledData.add(e);
- new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
- .delete();
- new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
- .createNewFile();
- } catch (RemoteException | IOException e) {
- Slog.e(TAG, "Getting procstats failed: ", e);
- return StatsManager.PULL_SKIP;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
+ .delete();
+ new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
+ .createNewFile();
+ } catch (RemoteException | IOException e) {
+ Slog.e(TAG, "Getting procstats failed: ", e);
+ return StatsManager.PULL_SKIP;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
return StatsManager.PULL_SUCCESS;
}
@@ -2461,7 +2628,7 @@
);
}
- int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
+ int pullDiskIOLocked(int atomTag, List<StatsEvent> pulledData) {
mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
fgFsync, bgFsync) -> {
@@ -2495,7 +2662,7 @@
);
}
- int pullPowerProfile(int atomTag, List<StatsEvent> pulledData) {
+ int pullPowerProfileLocked(int atomTag, List<StatsEvent> pulledData) {
PowerProfile powerProfile = new PowerProfile(mContext);
ProtoOutputStream proto = new ProtoOutputStream();
powerProfile.dumpDebug(proto);
@@ -2522,25 +2689,23 @@
);
}
- int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
- synchronized (mCpuTrackerLock) {
- if (mProcessCpuTracker == null) {
- mProcessCpuTracker = new ProcessCpuTracker(false);
- mProcessCpuTracker.init();
- }
- mProcessCpuTracker.update();
- for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
- ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
- StatsEvent e = StatsEvent.newBuilder()
- .setAtomId(atomTag)
- .writeInt(st.uid)
- .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
- .writeString(st.name)
- .writeLong(st.base_utime)
- .writeLong(st.base_stime)
- .build();
- pulledData.add(e);
- }
+ int pullProcessCpuTimeLocked(int atomTag, List<StatsEvent> pulledData) {
+ if (mProcessCpuTracker == null) {
+ mProcessCpuTracker = new ProcessCpuTracker(false);
+ mProcessCpuTracker.init();
+ }
+ mProcessCpuTracker.update();
+ for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
+ ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(st.uid)
+ .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
+ .writeString(st.name)
+ .writeLong(st.base_utime)
+ .writeLong(st.base_stime)
+ .build();
+ pulledData.add(e);
}
return StatsManager.PULL_SUCCESS;
}
@@ -2558,7 +2723,7 @@
);
}
- int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
+ int pullCpuTimePerThreadFreqLocked(int atomTag, List<StatsEvent> pulledData) {
if (this.mKernelCpuThreadReader == null) {
Slog.e(TAG, "mKernelCpuThreadReader is null");
return StatsManager.PULL_SKIP;
@@ -2617,23 +2782,27 @@
}
private BatteryStatsHelper getBatteryStatsHelper() {
- if (mBatteryStatsHelper == null) {
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
- mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
+ synchronized (mBatteryStatsHelperLock) {
+ if (mBatteryStatsHelper == null) {
+ final long callingToken = Binder.clearCallingIdentity();
+ try {
+ // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
+ mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
+ }
+ mBatteryStatsHelper.create((Bundle) null);
}
- mBatteryStatsHelper.create((Bundle) null);
- }
- long currentTime = SystemClock.elapsedRealtime();
- if (currentTime - mBatteryStatsHelperTimestampMs >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
- // Load BatteryStats and do all the calculations.
- mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.USER_ALL);
- // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
- mBatteryStatsHelper.clearStats();
- mBatteryStatsHelperTimestampMs = currentTime;
+ long currentTime = SystemClock.elapsedRealtime();
+ if (currentTime - mBatteryStatsHelperTimestampMs
+ >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
+ // Load BatteryStats and do all the calculations.
+ mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
+ UserHandle.USER_ALL);
+ // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
+ mBatteryStatsHelper.clearStats();
+ mBatteryStatsHelperTimestampMs = currentTime;
+ }
}
return mBatteryStatsHelper;
}
@@ -2652,7 +2821,7 @@
);
}
- int pullDeviceCalculatedPowerUse(int atomTag, List<StatsEvent> pulledData) {
+ int pullDeviceCalculatedPowerUseLocked(int atomTag, List<StatsEvent> pulledData) {
BatteryStatsHelper bsHelper = getBatteryStatsHelper();
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
@@ -2672,7 +2841,7 @@
);
}
- int pullDeviceCalculatedPowerBlameUid(int atomTag, List<StatsEvent> pulledData) {
+ int pullDeviceCalculatedPowerBlameUidLocked(int atomTag, List<StatsEvent> pulledData) {
final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
if (sippers == null) {
return StatsManager.PULL_SKIP;
@@ -2703,7 +2872,7 @@
);
}
- int pullDeviceCalculatedPowerBlameOther(int atomTag, List<StatsEvent> pulledData) {
+ int pullDeviceCalculatedPowerBlameOtherLocked(int atomTag, List<StatsEvent> pulledData) {
final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
if (sippers == null) {
return StatsManager.PULL_SKIP;
@@ -2739,41 +2908,37 @@
);
}
- int pullDebugElapsedClock(int atomTag, List<StatsEvent> pulledData) {
+ int pullDebugElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
final long elapsedMillis = SystemClock.elapsedRealtime();
+ final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
+ ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
- synchronized (mDebugElapsedClockLock) {
- final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
- ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(mDebugElapsedClockPullCount)
+ .writeLong(elapsedMillis)
+ // Log it twice to be able to test multi-value aggregation from ValueMetric.
+ .writeLong(elapsedMillis)
+ .writeLong(clockDiffMillis)
+ .writeInt(1 /* always set */)
+ .build();
+ pulledData.add(e);
- StatsEvent e = StatsEvent.newBuilder()
+ if (mDebugElapsedClockPullCount % 2 == 1) {
+ StatsEvent e2 = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeLong(mDebugElapsedClockPullCount)
.writeLong(elapsedMillis)
// Log it twice to be able to test multi-value aggregation from ValueMetric.
.writeLong(elapsedMillis)
.writeLong(clockDiffMillis)
- .writeInt(1 /* always set */)
+ .writeInt(2 /* set on odd pulls */)
.build();
- pulledData.add(e);
-
- if (mDebugElapsedClockPullCount % 2 == 1) {
- StatsEvent e2 = StatsEvent.newBuilder()
- .setAtomId(atomTag)
- .writeLong(mDebugElapsedClockPullCount)
- .writeLong(elapsedMillis)
- // Log it twice to be able to test multi-value aggregation from ValueMetric.
- .writeLong(elapsedMillis)
- .writeLong(clockDiffMillis)
- .writeInt(2 /* set on odd pulls */)
- .build();
- pulledData.add(e2);
- }
-
- mDebugElapsedClockPullCount++;
- mDebugElapsedClockPreviousValue = elapsedMillis;
+ pulledData.add(e2);
}
+ mDebugElapsedClockPullCount++;
+ mDebugElapsedClockPreviousValue = elapsedMillis;
return StatsManager.PULL_SUCCESS;
}
@@ -2790,31 +2955,27 @@
);
}
- int pullDebugFailingElapsedClock(int atomTag, List<StatsEvent> pulledData) {
+ int pullDebugFailingElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
final long elapsedMillis = SystemClock.elapsedRealtime();
-
- synchronized (mDebugFailingElapsedClockLock) {
- // Fails every 5 buckets.
- if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
- mDebugFailingElapsedClockPreviousValue = elapsedMillis;
- Slog.e(TAG, "Failing debug elapsed clock");
- return StatsManager.PULL_SKIP;
- }
-
- StatsEvent e = StatsEvent.newBuilder()
- .setAtomId(atomTag)
- .writeLong(mDebugFailingElapsedClockPullCount)
- .writeLong(elapsedMillis)
- // Log it twice to be able to test multi-value aggregation from ValueMetric.
- .writeLong(elapsedMillis)
- .writeLong(mDebugFailingElapsedClockPreviousValue == 0
- ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
- .build();
- pulledData.add(e);
-
+ // Fails every 5 buckets.
+ if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
mDebugFailingElapsedClockPreviousValue = elapsedMillis;
+ Slog.e(TAG, "Failing debug elapsed clock");
+ return StatsManager.PULL_SKIP;
}
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(mDebugFailingElapsedClockPullCount)
+ .writeLong(elapsedMillis)
+ // Log it twice to be able to test multi-value aggregation from ValueMetric.
+ .writeLong(elapsedMillis)
+ .writeLong(mDebugFailingElapsedClockPreviousValue == 0
+ ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
+ .build();
+ pulledData.add(e);
+
+ mDebugFailingElapsedClockPreviousValue = elapsedMillis;
return StatsManager.PULL_SUCCESS;
}
@@ -2828,7 +2989,7 @@
);
}
- int pullBuildInformation(int atomTag, List<StatsEvent> pulledData) {
+ int pullBuildInformationLocked(int atomTag, List<StatsEvent> pulledData) {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeString(Build.FINGERPRINT)
@@ -2856,7 +3017,7 @@
}
// Add a RoleHolder atom for each package that holds a role.
- int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
+ int pullRoleHolderLocked(int atomTag, List<StatsEvent> pulledData) {
long callingToken = Binder.clearCallingIdentity();
try {
PackageManager pm = mContext.getPackageManager();
@@ -2914,7 +3075,7 @@
);
}
- int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
+ int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) {
final long token = Binder.clearCallingIdentity();
float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS,
DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.02f);
@@ -3007,7 +3168,7 @@
);
}
- int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullTimeZoneDataInfoLocked(int atomTag, List<StatsEvent> pulledData) {
String tzDbVersion = "Unknown";
try {
tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
@@ -3034,7 +3195,7 @@
);
}
- int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
if (mStorageManager == null) {
return StatsManager.PULL_SKIP;
}
@@ -3084,7 +3245,7 @@
);
}
- int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+ int pullAppsOnExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
if (mStorageManager == null) {
return StatsManager.PULL_SKIP;
}
@@ -3140,7 +3301,7 @@
);
}
- int pullFaceSettings(int atomTag, List<StatsEvent> pulledData) {
+ int pullFaceSettingsLocked(int atomTag, List<StatsEvent> pulledData) {
final long callingToken = Binder.clearCallingIdentity();
try {
List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
@@ -3222,7 +3383,7 @@
}
}
- int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
+ int pullAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
final long token = Binder.clearCallingIdentity();
try {
AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
@@ -3299,7 +3460,7 @@
);
}
- int pullAttributedAppOps(int atomTag, List<StatsEvent> pulledData) {
+ int pullAttributedAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
final long token = Binder.clearCallingIdentity();
try {
AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
@@ -3377,7 +3538,9 @@
}
int estimatedSamplingRate = (int) constrain(
appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100);
- mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate);
+ synchronized (mAppOpsSamplingRateLock) {
+ mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate);
+ }
}
private List<AppOpEntry> processHistoricalOps(
@@ -3420,7 +3583,7 @@
}
}
- int pullRuntimeAppOpAccessMessage(int atomTag, List<StatsEvent> pulledData) {
+ int pullRuntimeAppOpAccessMessageLocked(int atomTag, List<StatsEvent> pulledData) {
final long token = Binder.clearCallingIdentity();
try {
AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
@@ -3507,7 +3670,7 @@
);
}
- int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
+ int pullNotificationRemoteViewsLocked(int atomTag, List<StatsEvent> pulledData) {
INotificationManager notificationManagerService = getINotificationManagerService();
if (notificationManagerService == null) {
return StatsManager.PULL_SKIP;
@@ -3601,7 +3764,7 @@
);
}
- int pullHealthHal(int atomTag, List<StatsEvent> pulledData) {
+ int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
IHealth healthService = mHealthService.getLastService();
if (healthService == null) {
return StatsManager.PULL_SKIP;
@@ -3651,7 +3814,7 @@
);
}
- int pullSettingsStats(int atomTag, List<StatsEvent> pulledData) {
+ int pullSettingsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
UserManager userManager = mContext.getSystemService(UserManager.class);
if (userManager == null) {
return StatsManager.PULL_SKIP;
@@ -3678,21 +3841,6 @@
return StatsManager.PULL_SUCCESS;
}
- private void registerDisplayWakeStats() {
- int tagId = FrameworkStatsLog.DISPLAY_WAKE_REASON;
- mStatsManager.setPullAtomCallback(
- tagId,
- null, // use default PullAtomMetadata values
- DIRECT_EXECUTOR,
- mStatsCallbackImpl
- );
- }
-
- int pullDisplayWakeStats(int atomTag, List<StatsEvent> pulledData) {
- //TODO: Denny, implement read/write DisplayWakeStats, b/154172964
- return 0;
- }
-
// Thermal event received from vendor thermal management subsystem
private static final class ThermalEventListener extends IThermalEventListener.Stub {
@Override
@@ -3749,11 +3897,13 @@
final SubInfo subInfo = new SubInfo(subId, sub.getCarrierId(), mcc, mnc,
subscriberId, sub.isOpportunistic());
Slog.i(TAG, "subId " + subId + " added into historical sub list");
- mHistoricalSubs.add(subInfo);
- // Since getting snapshot when pulling will also include data before boot,
- // query stats as baseline to prevent double count is needed.
- mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
+ synchronized (mDataBytesTransferLock) {
+ mHistoricalSubs.add(subInfo);
+ // Since getting snapshot when pulling will also include data before boot,
+ // query stats as baseline to prevent double count is needed.
+ mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index c18a6eb..94a2502 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -413,20 +413,18 @@
resetUserSessions();
}
};
- }
- Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
- if (mContext.bindServiceAsUser(new Intent().setComponent(name), mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
- UserHandle.of(mUserId))) {
- Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
- return mLatch;
- } else {
- synchronized (mLock) {
+ Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
+ if (mContext.bindServiceAsUser(new Intent().setComponent(name), mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.of(mUserId))) {
+ Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
+ return mLatch;
+ } else {
mIsConnecting = false;
+ throw new ExternalStorageServiceException(
+ "Failed to bind to the ExternalStorageService for user " + mUserId);
}
- throw new ExternalStorageServiceException(
- "Failed to bind to the ExternalStorageService for user " + mUserId);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d1366bd..a8f3ae5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5616,11 +5616,6 @@
mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
mExitAnimId = exitAnim;
mEnterAnimId = enterAnim;
- ScreenRotationAnimation screenRotationAnimation =
- displayContent.getRotationAnimation();
- if (screenRotationAnimation != null) {
- screenRotationAnimation.kill();
- }
displayContent.updateDisplayInfo();
final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f1064d1..df55b3b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2616,6 +2616,8 @@
mSetupContentObserver = new SetupContentObserver(mHandler);
mUserManagerInternal.addUserRestrictionsListener(new RestrictionsListener(mContext));
+
+ loadOwners();
}
/**
@@ -2676,12 +2678,23 @@
}
}
+ /**
+ * Load information about device and profile owners of the device, populating mOwners and
+ * pushing owner info to other system services. This is called at a fairly early stage of
+ * system server initialiation (via DevicePolicyManagerService's ctor), so care should to
+ * be taken to not interact with system services that are initialiated after DPMS.
+ * onLockSettingsReady() is a safer place to do initialization work not critical during
+ * the first boot stage.
+ * Note this only loads the list of owners, and not their actual policy (DevicePolicyData).
+ * The policy is normally loaded lazily when it's first accessed. In several occasions
+ * the list of owners is necessary for providing callers with aggregated policies across
+ * multiple owners, hence the owner list is loaded as part of DPMS's construction here.
+ */
void loadOwners() {
synchronized (getLockObject()) {
mOwners.load();
setDeviceOwnershipSystemPropertyLocked();
findOwnerComponentIfNecessaryLocked();
- migrateUserRestrictionsIfNecessaryLocked();
// TODO PO may not have a class name either due to b/17652534. Address that too.
updateDeviceOwnerLocked();
@@ -4104,8 +4117,10 @@
}
private void onLockSettingsReady() {
+ synchronized (getLockObject()) {
+ migrateUserRestrictionsIfNecessaryLocked();
+ }
getUserData(UserHandle.USER_SYSTEM);
- loadOwners();
cleanUpOldUsers();
maybeSetDefaultProfileOwnerUserRestrictions();
handleStartUser(UserHandle.USER_SYSTEM);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 48e70e0..c44f127 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -57,6 +57,7 @@
private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
private int mPlaybackPhysicalAddress;
private boolean mWokenUp;
+ private boolean mStandby;
@Mock private IPowerManager mIPowerManagerMock;
@Mock private IThermalService mIThermalServiceMock;
@@ -77,6 +78,11 @@
}
@Override
+ void standby() {
+ mStandby = true;
+ }
+
+ @Override
boolean isControlEnabled() {
return true;
}
@@ -337,6 +343,52 @@
}
@Test
+ public void handleActiveSource_ActiveSource_None() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE;
+ mStandby = false;
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+ assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleActiveSource_notActiveSource_None() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE;
+ mStandby = false;
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleActiveSource_ActiveSource_StandbyNow() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW;
+ mStandby = false;
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+ assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleActiveSource_notActiveSource_StandbyNow() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ Constants.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW;
+ mStandby = false;
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mStandby).isTrue();
+ }
+
+ @Test
public void sendVolumeKeyEvent_up_volumeEnabled() {
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index 80b474f..6991c18 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -360,13 +360,12 @@
mDataBase.new WriteBufferRunnable();
mDataBase.mBuffer = nh;
- wbr.currentTime = 5;
- wbr.latestNotificationsFile = mock(AtomicFile.class);
+ AtomicFile af = mock(AtomicFile.class);
File file = mock(File.class);
when(file.getName()).thenReturn("5");
- when(wbr.latestNotificationsFile.getBaseFile()).thenReturn(file);
+ when(af.getBaseFile()).thenReturn(file);
- wbr.run();
+ wbr.run(5, af);
assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(1);
assertThat(mDataBase.mBuffer).isNotEqualTo(nh);
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 2e4e7f5..7b86b08 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -1381,4 +1381,26 @@
public String getWapiCertSuite() {
return getFieldValue(WAPI_CERT_SUITE_KEY);
}
+
+ /**
+ * Method determines whether the Enterprise configuration is insecure. An insecure
+ * configuration is one where EAP method requires a CA certification, i.e. PEAP, TLS, or
+ * TTLS, and any of the following conditions are met:
+ * - Both certificate and CA path are not configured.
+ * - Both alternative subject match and domain suffix match are not set.
+ *
+ * Note: this method does not exhaustively check security of the configuration - i.e. a return
+ * value of {@code false} is not a guarantee that the configuration is secure.
+ * @hide
+ */
+ public boolean isInsecure() {
+ if (mEapMethod != Eap.PEAP && mEapMethod != Eap.TLS && mEapMethod != Eap.TTLS) {
+ return false;
+ }
+ if (!mIsAppInstalledCaCert && TextUtils.isEmpty(getCaPath())) {
+ return true;
+ }
+ return TextUtils.isEmpty(getAltSubjectMatch()) && TextUtils.isEmpty(
+ getDomainSuffixMatch());
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 8c494943..4d3a2c0 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -257,28 +257,38 @@
/**
* Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
+ * to WPA2 enterprise networks. See {@link WifiEnterpriseConfig} for description.
*
* @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
* @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if configuration CA certificate or
+ * AltSubjectMatch/DomainSuffixMatch is not set.
*/
public @NonNull Builder setWpa2EnterpriseConfig(
@NonNull WifiEnterpriseConfig enterpriseConfig) {
checkNotNull(enterpriseConfig);
+ if (enterpriseConfig.isInsecure()) {
+ throw new IllegalArgumentException("Enterprise configuration is insecure");
+ }
mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
return this;
}
/**
* Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
+ * to WPA3 enterprise networks. See {@link WifiEnterpriseConfig} for description.
*
* @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
* @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if configuration CA certificate or
+ * AltSubjectMatch/DomainSuffixMatch is not set.
*/
public @NonNull Builder setWpa3EnterpriseConfig(
@NonNull WifiEnterpriseConfig enterpriseConfig) {
checkNotNull(enterpriseConfig);
+ if (enterpriseConfig.isInsecure()) {
+ throw new IllegalArgumentException("Enterprise configuration is insecure");
+ }
mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
return this;
}
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index 320c187..268645c 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -47,6 +47,7 @@
public static final String KEYSTORE_URI = "keystore://";
public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
public static final String KEYSTORES_URI = "keystores://";
+ private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
private WifiEnterpriseConfig mEnterpriseConfig;
@@ -540,4 +541,30 @@
mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS);
assertEquals(null, getSupplicantPhase2Method());
}
+
+ @Test
+ public void testIsEnterpriseConfigSecure() {
+ WifiEnterpriseConfig baseConfig = new WifiEnterpriseConfig();
+ baseConfig.setEapMethod(Eap.PEAP);
+ baseConfig.setPhase2Method(Phase2.MSCHAPV2);
+ assertTrue(baseConfig.isInsecure());
+
+ WifiEnterpriseConfig noMatchConfig = new WifiEnterpriseConfig(baseConfig);
+ noMatchConfig.setCaCertificate(FakeKeys.CA_CERT0);
+ // Missing match is insecure.
+ assertTrue(noMatchConfig.isInsecure());
+
+ WifiEnterpriseConfig noCaConfig = new WifiEnterpriseConfig(baseConfig);
+ noCaConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+ // Missing CA certificate is insecure.
+ assertTrue(noCaConfig.isInsecure());
+
+ WifiEnterpriseConfig secureConfig = new WifiEnterpriseConfig();
+ secureConfig.setEapMethod(Eap.PEAP);
+ secureConfig.setPhase2Method(Phase2.MSCHAPV2);
+ secureConfig.setCaCertificate(FakeKeys.CA_CERT0);
+ secureConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+ assertFalse(secureConfig.isInsecure());
+ }
+
}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index d1d1c61..16b4ad0 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -38,6 +38,7 @@
private static final String TEST_PRESHARED_KEY = "Test123";
private static final String TEST_FQDN = "fqdn";
private static final String TEST_WAPI_CERT_SUITE = "suite";
+ private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
/**
* Validate correctness of WifiNetworkSuggestion object created by
@@ -208,6 +209,8 @@
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
.setSsid(TEST_SSID)
@@ -230,6 +233,40 @@
}
/**
+ * Ensure create enterprise suggestion requires CA, when CA certificate is missing, will throw
+ * an exception.
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutCa() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2EnterpriseConfig(enterpriseConfig)
+ .build();
+ }
+
+ /**
+ * Ensure create enterprise suggestion requires CA, when both domain suffix and alt subject
+ * match are missing, will throw an exception.
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutMatch() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
+
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+ }
+
+ /**
* Validate correctness of WifiNetworkSuggestion object created by
* {@link WifiNetworkSuggestion.Builder#build()} for WAPI-PSK network.
*/