Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-dev
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index 88acf65..c43c832 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -281,6 +281,20 @@
boolean shouldNoteResponseEventForAllBroadcastSessions();
/**
+ * Returns the list of roles whose holders are exempted from the requirement of starting
+ * a response event after receiving a broadcast.
+ */
+ @NonNull
+ List<String> getBroadcastResponseExemptedRoles();
+
+ /**
+ * Returns the list of permissions whose holders are exempted from the requirement of starting
+ * a response event after receiving a broadcast.
+ */
+ @NonNull
+ List<String> getBroadcastResponseExemptedPermissions();
+
+ /**
* Return the last known value corresponding to the {@code key} from
* {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController.
*/
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index c1f31e9..9e3e355 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -100,6 +100,7 @@
import android.provider.DeviceConfig;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
@@ -421,6 +422,26 @@
ConstantsObserver.DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS;
/**
+ * List of roles whose holders are exempted from the requirement of starting
+ * a response event after receiving a broadcast.
+ *
+ * The list of roles will be separated by '|' in the string.
+ */
+ volatile String mBroadcastResponseExemptedRoles =
+ ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES;
+ volatile List<String> mBroadcastResponseExemptedRolesList = Collections.EMPTY_LIST;
+
+ /**
+ * List of permissions whose holders are exempted from the requirement of starting
+ * a response event after receiving a broadcast.
+ *
+ * The list of permissions will be separated by '|' in the string.
+ */
+ volatile String mBroadcastResponseExemptedPermissions =
+ ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS;
+ volatile List<String> mBroadcastResponseExemptedPermissionsList = Collections.EMPTY_LIST;
+
+ /**
* Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}.
*
* Note: We are intentionally not guarding this by any lock since this is only updated on
@@ -1960,6 +1981,18 @@
}
@Override
+ @NonNull
+ public List<String> getBroadcastResponseExemptedRoles() {
+ return mBroadcastResponseExemptedRolesList;
+ }
+
+ @Override
+ @NonNull
+ public List<String> getBroadcastResponseExemptedPermissions() {
+ return mBroadcastResponseExemptedPermissionsList;
+ }
+
+ @Override
@Nullable
public String getAppStandbyConstant(@NonNull String key) {
return mAppStandbyProperties.get(key);
@@ -2311,6 +2344,14 @@
pw.print(mNoteResponseEventForAllBroadcastSessions);
pw.println();
+ pw.print(" mBroadcastResponseExemptedRoles");
+ pw.print(mBroadcastResponseExemptedRoles);
+ pw.println();
+
+ pw.print(" mBroadcastResponseExemptedPermissions");
+ pw.print(mBroadcastResponseExemptedPermissions);
+ pw.println();
+
pw.println();
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
pw.print(" mAllowRestrictedBucket=");
@@ -2795,6 +2836,10 @@
"broadcast_sessions_with_response_duration_ms";
private static final String KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS =
"note_response_event_for_all_broadcast_sessions";
+ private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES =
+ "brodacast_response_exempted_roles";
+ private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS =
+ "brodacast_response_exempted_permissions";
public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS =
COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR;
@@ -2837,6 +2882,11 @@
2 * ONE_MINUTE;
public static final boolean DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS =
true;
+ private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES = "";
+ private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS = "";
+
+ private final TextUtils.SimpleStringSplitter mStringPipeSplitter =
+ new TextUtils.SimpleStringSplitter('|');
ConstantsObserver(Handler handler) {
super(handler);
@@ -2989,6 +3039,20 @@
KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS,
DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS);
break;
+ case KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES:
+ mBroadcastResponseExemptedRoles = properties.getString(
+ KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES,
+ DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES);
+ mBroadcastResponseExemptedRolesList = splitPipeSeparatedString(
+ mBroadcastResponseExemptedRoles);
+ break;
+ case KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS:
+ mBroadcastResponseExemptedPermissions = properties.getString(
+ KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS,
+ DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS);
+ mBroadcastResponseExemptedPermissionsList = splitPipeSeparatedString(
+ mBroadcastResponseExemptedPermissions);
+ break;
default:
if (!timeThresholdsUpdated
&& (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD)
@@ -3003,6 +3067,15 @@
}
}
+ private List<String> splitPipeSeparatedString(String string) {
+ final List<String> values = new ArrayList<>();
+ mStringPipeSplitter.setString(string);
+ while (mStringPipeSplitter.hasNext()) {
+ values.add(mStringPipeSplitter.next());
+ }
+ return values;
+ }
+
private void updateTimeThresholds() {
// Query the values as an atomic set.
final DeviceConfig.Properties screenThresholdProperties =
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c6f5920..1d1743f5 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -298,6 +298,11 @@
/** Use background GC policy and default JIT threshold. */
private static final int VM_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
+ /** The delay time for retrying to request DirectActions. */
+ private static final long REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS = 200;
+ /** The max count for retrying to request DirectActions. */
+ private static final int REQUEST_DIRECT_ACTIONS_RETRY_MAX_COUNT = 7;
+
/**
* Denotes an invalid sequence number corresponding to a process state change.
*/
@@ -1864,7 +1869,8 @@
cancellationCallback.sendResult(cancellationResult);
}
mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
- ActivityThread.this, activityToken, interactor, cancellationSignal, callback));
+ ActivityThread.this, activityToken, interactor, cancellationSignal, callback,
+ REQUEST_DIRECT_ACTIONS_RETRY_MAX_COUNT));
}
@Override
@@ -3970,7 +3976,7 @@
/** Fetches the user actions for the corresponding activity */
private void handleRequestDirectActions(@NonNull IBinder activityToken,
@NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal,
- @NonNull RemoteCallback callback) {
+ @NonNull RemoteCallback callback, int retryCount) {
final ActivityClientRecord r = mActivities.get(activityToken);
if (r == null) {
Log.w(TAG, "requestDirectActions(): no activity for " + activityToken);
@@ -3978,7 +3984,20 @@
return;
}
final int lifecycleState = r.getLifecycleState();
- if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
+ if (lifecycleState < ON_START) {
+ // TODO(b/234173463): requestDirectActions callback should indicate errors
+ if (retryCount > 0) {
+ mH.sendMessageDelayed(
+ PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
+ ActivityThread.this, activityToken, interactor, cancellationSignal,
+ callback, retryCount - 1), REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS);
+ return;
+ }
+ Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState);
+ callback.sendResult(null);
+ return;
+ }
+ if (lifecycleState >= ON_STOP) {
Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState);
callback.sendResult(null);
return;
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index ef46624..067a4c3 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -36,6 +36,7 @@
import com.android.internal.graphics.palette.CelebiQuantizer;
import com.android.internal.graphics.palette.Palette;
import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
+import com.android.internal.util.ContrastColorUtil;
import java.io.FileOutputStream;
import java.lang.annotation.Retention;
@@ -93,10 +94,18 @@
// using the area instead. This way our comparisons are aspect ratio independent.
private static final int MAX_WALLPAPER_EXTRACTION_AREA = MAX_BITMAP_SIZE * MAX_BITMAP_SIZE;
- // Decides when dark theme is optimal for this wallpaper.
- // The midpoint of perceptual luminance, 50, is 18.42 in relative luminance.
- // ColorUtils.calculateLuminance returns relative luminance on a scale from 0 to 1.
- private static final float DARK_THEME_MEAN_LUMINANCE = 0.1842f;
+ // When extracting the main colors, only consider colors
+ // present in at least MIN_COLOR_OCCURRENCE of the image
+ private static final float MIN_COLOR_OCCURRENCE = 0.05f;
+
+ // Decides when dark theme is optimal for this wallpaper
+ private static final float DARK_THEME_MEAN_LUMINANCE = 0.3f;
+ // Minimum mean luminosity that an image needs to have to support dark text
+ private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.7f;
+ // We also check if the image has dark pixels in it,
+ // to avoid bright images with some dark spots.
+ private static final float DARK_PIXEL_CONTRAST = 5.5f;
+ private static final float MAX_DARK_AREA = 0.05f;
private final List<Color> mMainColors;
private final Map<Integer, Integer> mAllColors;
@@ -244,9 +253,12 @@
this(primaryColor, secondaryColor, tertiaryColor, 0);
// Calculate dark theme support based on primary color.
- final double relativeLuminance = ColorUtils.calculateLuminance(primaryColor.toArgb());
- final boolean wallpaperIsDark = relativeLuminance < DARK_THEME_MEAN_LUMINANCE;
- mColorHints |= wallpaperIsDark ? HINT_SUPPORTS_DARK_THEME : HINT_SUPPORTS_DARK_TEXT;
+ final float[] tmpHsl = new float[3];
+ ColorUtils.colorToHSL(primaryColor.toArgb(), tmpHsl);
+ final float luminance = tmpHsl[2];
+ if (luminance < DARK_THEME_MEAN_LUMINANCE) {
+ mColorHints |= HINT_SUPPORTS_DARK_THEME;
+ }
}
/**
@@ -524,6 +536,9 @@
dimAmount = MathUtils.saturate(dimAmount);
int[] pixels = new int[source.getWidth() * source.getHeight()];
+ double totalLuminance = 0;
+ final int maxDarkPixels = (int) (pixels.length * MAX_DARK_AREA);
+ int darkPixels = 0;
source.getPixels(pixels, 0 /* offset */, source.getWidth(), 0 /* x */, 0 /* y */,
source.getWidth(), source.getHeight());
@@ -532,70 +547,42 @@
int dimmingLayerAlpha = (int) (255 * dimAmount);
int blackTransparent = ColorUtils.setAlphaComponent(Color.BLACK, dimmingLayerAlpha);
- // The median luminance in the wallpaper will be used to decide if it is light or dark.
- //
- // Calculating the luminances, adding them to a data structure, then selecting
- // the middle element would be expensive, the sort would be O(n), where n is the number
- // of pixels.
- //
- // Instead, we create an integer array with 101 elements initialized to zero.
- // Why 101? 0 through 100, inclusive, matching the range of luminance.
- // Then, for each pixel, the luminance is calculated, and the integer at the array index
- // equal to the rounded luminance is incremented.
- //
- // After processing the pixels, the median luminance is determined by iterating over the
- // array containing the count for each luminance. Starting from 0, we adding the count at
- // each index until pixels.length/2 is exceeded. When that occurs, it means the current
- // array index contains the pixel of median luminance, thus the current array index is the
- // median luminance.
- int[] luminanceCounts = new int[101];
+ // This bitmap was already resized to fit the maximum allowed area.
+ // Let's just loop through the pixels, no sweat!
+ float[] tmpHsl = new float[3];
for (int i = 0; i < pixels.length; i++) {
int pixelColor = pixels[i];
+ ColorUtils.colorToHSL(pixelColor, tmpHsl);
final int alpha = Color.alpha(pixelColor);
- if (alpha == 0) {
- continue;
+
+ // Apply composite colors where the foreground is a black layer with an alpha value of
+ // the dim amount and the background is the wallpaper pixel color.
+ int compositeColors = ColorUtils.compositeColors(blackTransparent, pixelColor);
+
+ // Calculate the adjusted luminance of the dimmed wallpaper pixel color.
+ double adjustedLuminance = ColorUtils.calculateLuminance(compositeColors);
+
+ // Make sure we don't have a dark pixel mass that will
+ // make text illegible.
+ final boolean satisfiesTextContrast = ContrastColorUtil
+ .calculateContrast(pixelColor, Color.BLACK) > DARK_PIXEL_CONTRAST;
+ if (!satisfiesTextContrast && alpha != 0) {
+ darkPixels++;
+ if (DEBUG_DARK_PIXELS) {
+ pixels[i] = Color.RED;
+ }
}
-
- // If the wallpaper is dimmed, apply dimming before calculating luminance.
- int compositeColor = dimAmount <= 0 ? pixelColor :
- ColorUtils.compositeColors(blackTransparent, pixelColor);
-
- // calculateLuminance will return relative luminance on a scale from 0 to 1. Intent
- // is normalize to 0 to 100, and that is done by defensively normalizing to
- // luminanceCounts.length, then flooring the result to defensively avoid any imprecision
- // in the result of calculateLuminance that could cause it to exceed 1 and thus the
- // array bounds.
- float relativeLuminance = (float) ColorUtils.calculateLuminance(compositeColor)
- * luminanceCounts.length - 1;
- int intRelativeLuminance = (int) Math.floor(relativeLuminance);
- int clampedRelativeLuminance = (intRelativeLuminance < 0) ? 0 :
- (intRelativeLuminance > luminanceCounts.length - 1) ? luminanceCounts.length - 1
- : intRelativeLuminance;
- luminanceCounts[clampedRelativeLuminance] += 1;
+ totalLuminance += adjustedLuminance;
}
- int criticalRelativeLuminance = 0;
- int luminancesProcessed = 0;
- int criticalLuminanceIndex = (int) Math.floor(pixels.length * 0.5);
- for (int i = 0; i < 100; i++) {
- luminancesProcessed += luminanceCounts[i];
- if (luminancesProcessed > criticalLuminanceIndex) {
- criticalRelativeLuminance = i;
- break;
- }
- }
-
- // Wallpaper is dark if the median pixel is less than mid-gray.
- //
- // Relative luminance places mid-gray at 18.42, 19 is used since luminances were rounded to
- // ints to be stored in the array.
- //
- // Why not use perceptual luminance? It would require one more conversion step at each
- // pixel, or adding a function to convert relative luminance to perceptual luminance just
- // for this line.
- boolean wallpaperIsDark = criticalRelativeLuminance < 19;
int hints = 0;
- hints |= wallpaperIsDark ? HINT_SUPPORTS_DARK_THEME : HINT_SUPPORTS_DARK_TEXT;
+ double meanLuminance = totalLuminance / pixels.length;
+ if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
+ hints |= HINT_SUPPORTS_DARK_TEXT;
+ }
+ if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
+ hints |= HINT_SUPPORTS_DARK_THEME;
+ }
if (DEBUG_DARK_PIXELS) {
try (FileOutputStream out = new FileOutputStream("/data/pixels.png")) {
@@ -605,8 +592,8 @@
} catch (Exception e) {
e.printStackTrace();
}
- Log.d("WallpaperColors", "median relative L: " + criticalRelativeLuminance
- + ", numPixels: " + pixels.length);
+ Log.d("WallpaperColors", "l: " + meanLuminance + ", d: " + darkPixels +
+ " maxD: " + maxDarkPixels + " numPixels: " + pixels.length);
}
return hints;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 21ecf8b..334a659 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -806,11 +806,6 @@
@NonNull EditorInfo editorInfo, boolean restarting,
@NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags,
@NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
- mImeDispatcher = imeDispatcher;
- if (mWindow != null) {
- mWindow.getOnBackInvokedDispatcher().setImeOnBackInvokedDispatcher(
- imeDispatcher);
- }
mPrivOps.reportStartInputAsync(startInputToken);
mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
if (restarting) {
@@ -818,6 +813,15 @@
} else {
startInput(inputConnection, editorInfo);
}
+ // Update the IME dispatcher last, so that the previously registered back callback
+ // (if any) can be unregistered using the old dispatcher if {@link #doFinishInput()}
+ // is called from {@link #startInput(InputConnection, EditorInfo)} or
+ // {@link #restartInput(InputConnection, EditorInfo)}.
+ mImeDispatcher = imeDispatcher;
+ if (mWindow != null) {
+ mWindow.getOnBackInvokedDispatcher().setImeOnBackInvokedDispatcher(
+ imeDispatcher);
+ }
}
/**
@@ -3860,6 +3864,11 @@
};
private void compatHandleBack() {
+ if (!mDecorViewVisible) {
+ Log.e(TAG, "Back callback invoked on a hidden IME. Removing the callback...");
+ unregisterCompatOnBackInvokedCallback();
+ return;
+ }
final KeyEvent downEvent = createBackKeyEvent(
KeyEvent.ACTION_DOWN, false /* isTracking */);
onKeyDown(KeyEvent.KEYCODE_BACK, downEvent);
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index 3cffeb0..380c104 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -254,8 +254,9 @@
int GPU_COMPLETED = 19;
int SWAP_BUFFERS_COMPLETED = 20;
int DISPLAY_PRESENT_TIME = 21;
+ int COMMAND_SUBMISSION_COMPLETED = 22;
- int FRAME_STATS_COUNT = 22; // must always be last and in sync with
+ int FRAME_STATS_COUNT = 23; // must always be last and in sync with
// FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
}
@@ -291,7 +292,7 @@
// RESERVED VSYNC_TIMESTAMP
0, 0,
// GPU_DURATION
- Index.SWAP_BUFFERS, Index.GPU_COMPLETED,
+ Index.COMMAND_SUBMISSION_COMPLETED, Index.GPU_COMPLETED,
// DEADLINE
Index.INTENDED_VSYNC, Index.FRAME_DEADLINE,
};
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 0b05d94..2922ad6 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -210,6 +210,7 @@
.append(", scaleFactor=").append(scaleFactor)
.append(", transform=").append(transform)
.append(", windowToken=").append(windowToken)
+ .append(", isClone=").append(isClone)
.toString();
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 2e48c2b..7e264ce 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -719,13 +719,8 @@
private void releaseSurfaces(boolean releaseSurfacePackage) {
mSurfaceAlpha = 1f;
-
- mSurfaceLock.lock();
- try {
- mSurface.destroy();
- } finally {
- mSurfaceLock.unlock();
- }
+ mSurface.destroy();
+
synchronized (mSurfaceControlLock) {
if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy();
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7353bbc..7d7270d 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -522,6 +522,61 @@
public static final int RESULT_CODE_NOT_SERVICE = -1;
/**
+ * Reasons to commit the Autofill context.
+ *
+ * <p>If adding a new reason, modify
+ * {@link com.android.server.autofill.PresentationStatsEventLogger#getNoPresentationEventReason(int)}
+ * as well.</p>
+ *
+ * TODO(b/233833662): Expose this as a public API in U.
+ * @hide
+ */
+ @IntDef(prefix = { "COMMIT_REASON_" }, value = {
+ COMMIT_REASON_UNKNOWN,
+ COMMIT_REASON_ACTIVITY_FINISHED,
+ COMMIT_REASON_VIEW_COMMITTED,
+ COMMIT_REASON_VIEW_CLICKED,
+ COMMIT_REASON_VIEW_CHANGED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AutofillCommitReason {}
+
+ /**
+ * Autofill context was committed because of an unknown reason.
+ *
+ * @hide
+ */
+ public static final int COMMIT_REASON_UNKNOWN = 0;
+
+ /**
+ * Autofill context was committed because activity finished.
+ *
+ * @hide
+ */
+ public static final int COMMIT_REASON_ACTIVITY_FINISHED = 1;
+
+ /**
+ * Autofill context was committed because {@link #commit()} was called.
+ *
+ * @hide
+ */
+ public static final int COMMIT_REASON_VIEW_COMMITTED = 2;
+
+ /**
+ * Autofill context was committed because view was clicked.
+ *
+ * @hide
+ */
+ public static final int COMMIT_REASON_VIEW_CLICKED = 3;
+
+ /**
+ * Autofill context was committed because of view changed.
+ *
+ * @hide
+ */
+ public static final int COMMIT_REASON_VIEW_CHANGED = 4;
+
+ /**
* Makes an authentication id from a request id and a dataset id.
*
* @param requestId The request id.
@@ -1585,7 +1640,7 @@
}
if (mSaveTriggerId != null && mSaveTriggerId.equals(id)) {
if (sDebug) Log.d(TAG, "triggering commit by click of " + id);
- commitLocked();
+ commitLocked(/* commitReason= */ COMMIT_REASON_VIEW_CLICKED);
mMetricsLogger.write(newLog(MetricsEvent.AUTOFILL_SAVE_EXPLICITLY_TRIGGERED));
}
}
@@ -1603,7 +1658,7 @@
synchronized (mLock) {
if (mSaveOnFinish) {
if (sDebug) Log.d(TAG, "onActivityFinishing(): calling commitLocked()");
- commitLocked();
+ commitLocked(/* commitReason= */ COMMIT_REASON_ACTIVITY_FINISHED);
} else {
if (sDebug) Log.d(TAG, "onActivityFinishing(): calling cancelLocked()");
cancelLocked();
@@ -1628,16 +1683,16 @@
}
if (sVerbose) Log.v(TAG, "commit() called by app");
synchronized (mLock) {
- commitLocked();
+ commitLocked(/* commitReason= */ COMMIT_REASON_VIEW_COMMITTED);
}
}
@GuardedBy("mLock")
- private void commitLocked() {
+ private void commitLocked(@AutofillCommitReason int commitReason) {
if (!mEnabled && !isActiveLocked()) {
return;
}
- finishSessionLocked();
+ finishSessionLocked(/* commitReason= */ commitReason);
}
/**
@@ -2070,13 +2125,13 @@
}
@GuardedBy("mLock")
- private void finishSessionLocked() {
+ private void finishSessionLocked(@AutofillCommitReason int commitReason) {
if (sVerbose) Log.v(TAG, "finishSessionLocked(): " + getStateAsStringLocked());
if (!isActiveLocked()) return;
try {
- mService.finishSession(mSessionId, mContext.getUserId());
+ mService.finishSession(mSessionId, mContext.getUserId(), commitReason);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3549,7 +3604,7 @@
}
if (mVisibleTrackedIds == null) {
- finishSessionLocked();
+ finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
}
@@ -3582,9 +3637,9 @@
if (mVisibleTrackedIds == null) {
if (sVerbose) {
- Log.v(TAG, "No more visible ids. Invisibile = " + mInvisibleTrackedIds);
+ Log.v(TAG, "No more visible ids. Invisible = " + mInvisibleTrackedIds);
}
- finishSessionLocked();
+ finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
}
@@ -3656,7 +3711,7 @@
if (sVerbose) {
Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
}
- finishSessionLocked();
+ finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
}
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index a507e74..cefd6dc 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -49,7 +49,7 @@
void updateSession(int sessionId, in AutofillId id, in Rect bounds,
in AutofillValue value, int action, int flags, int userId);
void setAutofillFailure(int sessionId, in List<AutofillId> ids, int userId);
- void finishSession(int sessionId, int userId);
+ void finishSession(int sessionId, int userId, int commitReason);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);
void setHasCallback(int sessionId, int userId, boolean hasIt);
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index bedf503..10d43e8 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -90,7 +90,11 @@
synchronized (mLock) {
mCallbacks.add(Pair.create(callback, priority));
if (mActualDispatcher != null) {
- mActualDispatcher.registerOnBackInvokedCallback(priority, callback);
+ if (priority <= PRIORITY_SYSTEM) {
+ mActualDispatcher.registerSystemOnBackInvokedCallback(callback);
+ } else {
+ mActualDispatcher.registerOnBackInvokedCallback(priority, callback);
+ }
}
}
}
@@ -171,7 +175,16 @@
return;
}
clearCallbacksOnDispatcher();
- mActualDispatcher = actualDispatcher;
+ if (actualDispatcher instanceof ProxyOnBackInvokedDispatcher) {
+ // We don't want to nest ProxyDispatchers, so if we are given on, we unwrap its
+ // actual dispatcher.
+ // This can happen when an Activity is recreated but the Window is preserved (e.g.
+ // when going from split-screen back to single screen)
+ mActualDispatcher =
+ ((ProxyOnBackInvokedDispatcher) actualDispatcher).mActualDispatcher;
+ } else {
+ mActualDispatcher = actualDispatcher;
+ }
transferCallbacksToDispatcher();
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 61c844a..66abe30 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -300,6 +300,8 @@
@VisibleForTesting
protected ChooserMultiProfilePagerAdapter mChooserMultiProfilePagerAdapter;
+ private final EnterTransitionAnimationDelegate mEnterTransitionAnimationDelegate =
+ new EnterTransitionAnimationDelegate();
private boolean mRemoveSharedElements = false;
@@ -383,7 +385,7 @@
// transition animation.
getWindow().setWindowAnimations(0);
}
- startPostponedEnterTransition();
+ mEnterTransitionAnimationDelegate.markImagePreviewReady();
return true;
}
});
@@ -431,7 +433,7 @@
mHideParentOnFail = false;
}
mRemoveSharedElements = true;
- startPostponedEnterTransition();
+ mEnterTransitionAnimationDelegate.markImagePreviewReady();
}
}
@@ -724,7 +726,7 @@
mRemoveSharedElements = false;
}
});
- postponeEnterTransition();
+ mEnterTransitionAnimationDelegate.postponeTransition();
}
@Override
@@ -1242,6 +1244,9 @@
if (layout != null) {
adjustPreviewWidth(getResources().getConfiguration().orientation, layout);
}
+ if (previewType != CONTENT_PREVIEW_IMAGE) {
+ mEnterTransitionAnimationDelegate.markImagePreviewReady();
+ }
return layout;
}
@@ -2514,90 +2519,96 @@
if (mResolverDrawerLayout == null || gridAdapter == null) {
return;
}
-
- final int bottomInset = mSystemWindowInsets != null
- ? mSystemWindowInsets.bottom : 0;
- int offset = bottomInset;
- int rowsToShow = gridAdapter.getSystemRowCount()
- + gridAdapter.getProfileRowCount()
- + gridAdapter.getServiceTargetRowCount()
- + gridAdapter.getCallerAndRankedTargetRowCount();
-
- // then this is most likely not a SEND_* action, so check
- // the app target count
- if (rowsToShow == 0) {
- rowsToShow = gridAdapter.getRowCount();
- }
-
- // still zero? then use a default height and leave, which
- // can happen when there are no targets to show
- if (rowsToShow == 0 && !shouldShowStickyContentPreview()) {
- offset += getResources().getDimensionPixelSize(
- R.dimen.chooser_max_collapsed_height);
- mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
- return;
- }
-
- View stickyContentPreview = findViewById(R.id.content_preview_container);
- if (shouldShowStickyContentPreview() && isStickyContentPreviewShowing()) {
- offset += stickyContentPreview.getHeight();
- }
-
- if (shouldShowTabs()) {
- offset += findViewById(R.id.tabs).getHeight();
- }
-
- if (recyclerView.getVisibility() == View.VISIBLE) {
- int directShareHeight = 0;
- rowsToShow = Math.min(4, rowsToShow);
- boolean shouldShowExtraRow = shouldShowExtraRow(rowsToShow);
- mLastNumberOfChildren = recyclerView.getChildCount();
- for (int i = 0, childCount = recyclerView.getChildCount();
- i < childCount && rowsToShow > 0; i++) {
- View child = recyclerView.getChildAt(i);
- if (((GridLayoutManager.LayoutParams)
- child.getLayoutParams()).getSpanIndex() != 0) {
- continue;
- }
- int height = child.getHeight();
- offset += height;
- if (shouldShowExtraRow) {
- offset += height;
- }
-
- if (gridAdapter.getTargetType(
- recyclerView.getChildAdapterPosition(child))
- == ChooserListAdapter.TARGET_SERVICE) {
- directShareHeight = height;
- }
- rowsToShow--;
- }
-
- boolean isExpandable = getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
- if (directShareHeight != 0 && isSendAction(getTargetIntent())
- && isExpandable) {
- // make sure to leave room for direct share 4->8 expansion
- int requiredExpansionHeight =
- (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
- int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
- int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
- - requiredExpansionHeight - topInset - bottomInset;
-
- offset = Math.min(offset, minHeight);
- }
- } else {
- ViewGroup currentEmptyStateView = getActiveEmptyStateView();
- if (currentEmptyStateView.getVisibility() == View.VISIBLE) {
- offset += currentEmptyStateView.getHeight();
- }
- }
-
- mResolverDrawerLayout.setCollapsibleHeightReserved(Math.min(offset, bottom - top));
+ int offset = calculateDrawerOffset(top, bottom, recyclerView, gridAdapter);
+ mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
+ mEnterTransitionAnimationDelegate.markOffsetCalculated();
});
}
}
+ private int calculateDrawerOffset(
+ int top, int bottom, RecyclerView recyclerView, ChooserGridAdapter gridAdapter) {
+
+ final int bottomInset = mSystemWindowInsets != null
+ ? mSystemWindowInsets.bottom : 0;
+ int offset = bottomInset;
+ int rowsToShow = gridAdapter.getSystemRowCount()
+ + gridAdapter.getProfileRowCount()
+ + gridAdapter.getServiceTargetRowCount()
+ + gridAdapter.getCallerAndRankedTargetRowCount();
+
+ // then this is most likely not a SEND_* action, so check
+ // the app target count
+ if (rowsToShow == 0) {
+ rowsToShow = gridAdapter.getRowCount();
+ }
+
+ // still zero? then use a default height and leave, which
+ // can happen when there are no targets to show
+ if (rowsToShow == 0 && !shouldShowStickyContentPreview()) {
+ offset += getResources().getDimensionPixelSize(
+ R.dimen.chooser_max_collapsed_height);
+ return offset;
+ }
+
+ View stickyContentPreview = findViewById(R.id.content_preview_container);
+ if (shouldShowStickyContentPreview() && isStickyContentPreviewShowing()) {
+ offset += stickyContentPreview.getHeight();
+ }
+
+ if (shouldShowTabs()) {
+ offset += findViewById(R.id.tabs).getHeight();
+ }
+
+ if (recyclerView.getVisibility() == View.VISIBLE) {
+ int directShareHeight = 0;
+ rowsToShow = Math.min(4, rowsToShow);
+ boolean shouldShowExtraRow = shouldShowExtraRow(rowsToShow);
+ mLastNumberOfChildren = recyclerView.getChildCount();
+ for (int i = 0, childCount = recyclerView.getChildCount();
+ i < childCount && rowsToShow > 0; i++) {
+ View child = recyclerView.getChildAt(i);
+ if (((GridLayoutManager.LayoutParams)
+ child.getLayoutParams()).getSpanIndex() != 0) {
+ continue;
+ }
+ int height = child.getHeight();
+ offset += height;
+ if (shouldShowExtraRow) {
+ offset += height;
+ }
+
+ if (gridAdapter.getTargetType(
+ recyclerView.getChildAdapterPosition(child))
+ == ChooserListAdapter.TARGET_SERVICE) {
+ directShareHeight = height;
+ }
+ rowsToShow--;
+ }
+
+ boolean isExpandable = getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
+ if (directShareHeight != 0 && isSendAction(getTargetIntent())
+ && isExpandable) {
+ // make sure to leave room for direct share 4->8 expansion
+ int requiredExpansionHeight =
+ (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
+ int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
+ int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
+ - requiredExpansionHeight - topInset - bottomInset;
+
+ offset = Math.min(offset, minHeight);
+ }
+ } else {
+ ViewGroup currentEmptyStateView = getActiveEmptyStateView();
+ if (currentEmptyStateView.getVisibility() == View.VISIBLE) {
+ offset += currentEmptyStateView.getHeight();
+ }
+ }
+
+ return Math.min(offset, bottom - top);
+ }
+
/**
* If we have a tabbed view and are showing 1 row in the current profile and an empty
* state screen in the other profile, to prevent cropping of the empty state screen we show
@@ -3930,6 +3941,51 @@
}
}
+ /**
+ * A helper class to track app's readiness for the scene transition animation.
+ * The app is ready when both the image is laid out and the drawer offset is calculated.
+ */
+ private class EnterTransitionAnimationDelegate implements View.OnLayoutChangeListener {
+ private boolean mPreviewReady = false;
+ private boolean mOffsetCalculated = false;
+
+ void postponeTransition() {
+ postponeEnterTransition();
+ }
+
+ void markImagePreviewReady() {
+ if (!mPreviewReady) {
+ mPreviewReady = true;
+ maybeStartListenForLayout();
+ }
+ }
+
+ void markOffsetCalculated() {
+ if (!mOffsetCalculated) {
+ mOffsetCalculated = true;
+ maybeStartListenForLayout();
+ }
+ }
+
+ private void maybeStartListenForLayout() {
+ if (mPreviewReady && mOffsetCalculated && mResolverDrawerLayout != null) {
+ if (mResolverDrawerLayout.isInLayout()) {
+ startPostponedEnterTransition();
+ } else {
+ mResolverDrawerLayout.addOnLayoutChangeListener(this);
+ mResolverDrawerLayout.requestLayout();
+ }
+ }
+ }
+
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+ int oldTop, int oldRight, int oldBottom) {
+ v.removeOnLayoutChangeListener(this);
+ startPostponedEnterTransition();
+ }
+ }
+
@Override
protected void maybeLogProfileChange() {
getChooserActivityLogger().logShareheetProfileChanged();
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 777104d8..7c08a7b 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -543,6 +543,11 @@
*/
public static final String TASK_MANAGER_ENABLED = "task_manager_enabled";
+ /**
+ * (boolean) Whether the task manager should show an attention grabbing dot when tasks changed.
+ */
+ public static final String TASK_MANAGER_SHOW_FOOTER_DOT = "task_manager_show_footer_dot";
+
/**
* (boolean) Whether the clipboard overlay is enabled.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488fb180..f727d80 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -342,7 +342,7 @@
boolean mDecorFitsSystemWindows = true;
- private ProxyOnBackInvokedDispatcher mProxyOnBackInvokedDispatcher =
+ private final ProxyOnBackInvokedDispatcher mProxyOnBackInvokedDispatcher =
new ProxyOnBackInvokedDispatcher();
static class WindowManagerHolder {
@@ -378,6 +378,8 @@
// window, as we'll be skipping the addView in handleResumeActivity(), and
// the token will not be updated as for a new window.
getAttributes().token = preservedWindow.getAttributes().token;
+ mProxyOnBackInvokedDispatcher.setActualDispatcher(
+ preservedWindow.getOnBackInvokedDispatcher());
}
// Even though the device doesn't support picture-in-picture mode,
// an user can force using it through developer options.
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 90eeabb..1cdc108 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -929,7 +929,7 @@
// Single-use layout; just ignore the mode and use available space.
// Clamp to maxWidth.
if (mMaxWidth >= 0) {
- widthSize = Math.min(widthSize, mMaxWidth);
+ widthSize = Math.min(widthSize, mMaxWidth + getPaddingLeft() + getPaddingRight());
}
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
@@ -1008,8 +1008,9 @@
View indicatorHost = null;
int ypos = mTopOffset;
- int leftEdge = getPaddingLeft();
- int rightEdge = width - getPaddingRight();
+ final int leftEdge = getPaddingLeft();
+ final int rightEdge = width - getPaddingRight();
+ final int widthAvailable = rightEdge - leftEdge;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -1030,7 +1031,6 @@
final int bottom = top + child.getMeasuredHeight();
final int childWidth = child.getMeasuredWidth();
- final int widthAvailable = rightEdge - leftEdge;
final int left = leftEdge + (widthAvailable - childWidth) / 2;
final int right = left + childWidth;
diff --git a/core/proto/android/os/processstarttime.proto b/core/proto/android/os/processstarttime.proto
new file mode 100644
index 0000000..d0f8bae
--- /dev/null
+++ b/core/proto/android/os/processstarttime.proto
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+syntax = "proto2";
+package android.os;
+
+option java_multiple_files = true;
+
+// This message is used for statsd logging and should be kept in sync with
+// frameworks/proto_logging/stats/atoms.proto
+/**
+ * Logs information about process start time.
+ *
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
+ */
+message ProcessStartTime {
+ // The uid of the ProcessRecord.
+ optional int32 uid = 1;
+
+ // The process pid.
+ optional int32 pid = 2;
+
+ // The process name.
+ // Usually package name, "system" for system server.
+ // Provided by ActivityManagerService.
+ optional string process_name = 3;
+
+ enum StartType {
+ UNKNOWN = 0;
+ WARM = 1;
+ HOT = 2;
+ COLD = 3;
+ }
+
+ // The start type.
+ optional StartType type = 4;
+
+ // The elapsed realtime at the start of the process.
+ optional int64 process_start_time_millis = 5;
+
+ // Number of milliseconds it takes to reach bind application.
+ optional int32 bind_application_delay_millis = 6;
+
+ // Number of milliseconds it takes to finish start of the process.
+ optional int32 process_start_delay_millis = 7;
+
+ // hostingType field in ProcessRecord, the component type such as "activity",
+ // "service", "content provider", "broadcast" or other strings.
+ optional string hosting_type = 8;
+
+ // hostingNameStr field in ProcessRecord. The component class name that runs
+ // in this process.
+ optional string hosting_name = 9;
+
+ // Broadcast action name.
+ optional string broadcast_action_name = 10;
+
+ enum HostingTypeId {
+ HOSTING_TYPE_UNKNOWN = 0;
+ HOSTING_TYPE_ACTIVITY = 1;
+ HOSTING_TYPE_ADDED_APPLICATION = 2;
+ HOSTING_TYPE_BACKUP = 3;
+ HOSTING_TYPE_BROADCAST = 4;
+ HOSTING_TYPE_CONTENT_PROVIDER = 5;
+ HOSTING_TYPE_LINK_FAIL = 6;
+ HOSTING_TYPE_ON_HOLD = 7;
+ HOSTING_TYPE_NEXT_ACTIVITY = 8;
+ HOSTING_TYPE_NEXT_TOP_ACTIVITY = 9;
+ HOSTING_TYPE_RESTART = 10;
+ HOSTING_TYPE_SERVICE = 11;
+ HOSTING_TYPE_SYSTEM = 12;
+ HOSTING_TYPE_TOP_ACTIVITY = 13;
+ HOSTING_TYPE_EMPTY = 14;
+ }
+
+ optional HostingTypeId hosting_type_id = 11;
+}
+
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 1d67570..f816d0c 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -13,24 +13,23 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector android:height="128dp"
android:width="128dp"
- android:height="128dp"
- android:viewportWidth="128"
- android:viewportHeight="128">
- <path
- android:pathData="M64,64m-64,0a64,64 0,1 1,128 0a64,64 0,1 1,-128 0"
- android:fillColor="@android:color/system_accent3_500"/>
- <path
- android:pathData="M32.5,34.15a10,10 0,0 1,9.94 10V93.85"
- android:strokeWidth="4"
- android:fillColor="#00000000"
- android:strokeColor="#fff"
- android:strokeLineCap="round"/>
- <path
- android:pathData="M95.5,93.85H55.71V83.9A19.9,19.9 0,0 1,75.61 64h10a9.94,9.94 0,0 0,9.94 -10,19.9 19.9,0 0,0 -38.69,-6.56A20.77,20.77 0,0 0,56 50.73"
- android:strokeWidth="4"
- android:fillColor="#00000000"
- android:strokeColor="#fff"
- android:strokeLineCap="round"/>
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:pathData="M11 0.51a2.06 2.06 0 0 1 2 0l0.58 0.37a4.15 4.15 0 0 0 2.23 0.55l0.69-0.06a2.07 2.07 0 0 1 1.81 0.95l0.33 0.6a4.14 4.14 0 0 0 1.72 1.52l0.64 0.27a2 2 0 0 1 1.16 1.68l0 0.69A4.12 4.12 0 0 0 23 9.23l0.44 0.53a2.06 2.06 0 0 1 0.24 2l-0.3 0.62a4.14 4.14 0 0 0-0.27 2.28l0.14 0.68a2.08 2.08 0 0 1-0.72 1.91l-0.56 0.41a4 4 0 0 0-1.3 1.89l-0.19 0.66A2.06 2.06 0 0 1 19 21.58l-0.68 0.11a4.09 4.09 0 0 0-2 1.07l-0.48 0.5a2.08 2.08 0 0 1-2 0.49l-0.65-0.23a4.28 4.28 0 0 0-2.3 0l-0.65 0.23a2.08 2.08 0 0 1-2-0.49l-0.48-0.5a4 4 0 0 0-2-1.07L5 21.58A2.06 2.06 0 0 1 3.5 20.23l-0.19-0.66A4 4 0 0 0 2 17.68l-0.56-0.41a2.08 2.08 0 0 1-0.72-1.91l0.14-0.68A4.14 4.14 0 0 0 0.6 12.4l-0.3-0.62a2.06 2.06 0 0 1 0.24-2L1 9.23A4.16 4.16 0 0 0 1.8 7.08l0-0.69A2 2 0 0 1 3 4.71l0.64-0.27A4.14 4.14 0 0 0 5.34 2.92l0.33-0.6a2.07 2.07 0 0 1 1.81-0.95l0.69 0.06A4.15 4.15 0 0 0 10.4 0.88Z"
+ android:fillColor="@android:color/system_accent3_400"
+ />
+ <path
+ android:pathData="M12.34 6.53h4.05l-2 4.05a3.95 3.95 0 0 1-0.57 7.85 4.1 4.1 0 0 1-1.45-0.27"
+ android:strokeColor="@android:color/system_accent1_800"
+ android:strokeWidth="2"/>
+ <path
+ android:pathData="M12.34 6.53h4.05l-2 4.05a3.95 3.95 0 0 1-0.57 7.85 4.1 4.1 0 0 1-1.45-0.27"
+ android:strokeColor="@android:color/system_neutral1_100"
+ android:strokeWidth="0.5"/>
+
</vector>
+
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4d04edc..dceeb73 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1922,7 +1922,7 @@
<string name="language_selection_title" msgid="52674936078683285">"إضافة لغة"</string>
<string name="country_selection_title" msgid="5221495687299014379">"تفضيل المنطقة"</string>
<string name="search_language_hint" msgid="7004225294308793583">"اكتب اسم اللغة"</string>
- <string name="language_picker_section_suggested" msgid="6556199184638990447">"المناطق المقترحة"</string>
+ <string name="language_picker_section_suggested" msgid="6556199184638990447">"اللغات المقترَحة"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"جميع اللغات"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"كل المناطق"</string>
<string name="locale_search_menu" msgid="6258090710176422934">"البحث"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a3be5f0b..fae9dd7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1690,7 +1690,7 @@
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Funktionen auswählen, die du mit der Schaltfläche \"Bedienungshilfen\" verwenden möchtest"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funktionen für Verknüpfung mit Lautstärketaste auswählen"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> wurde deaktiviert"</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Verknüpfungen bearbeiten"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Kurzbefehle bearbeiten"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fertig"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Verknüpfung deaktivieren"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ac60235..54c3490 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2422,7 +2422,7 @@
<!-- Whether to dismiss the active dream when an activity is started. Doesn't apply to
assistant activities (ACTIVITY_TYPE_ASSISTANT) -->
- <bool name="config_dismissDreamOnActivityStart">true</bool>
+ <bool name="config_dismissDreamOnActivityStart">false</bool>
<!-- The prefix of dream component names that are loggable. If empty, logs "other" for all. -->
<string name="config_loggable_dream_prefix" translatable="false"></string>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 51ed856..f7c2b73 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1879,12 +1879,6 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
- "-240296576": {
- "message": "handleAppTransitionReady: displayId=%d appTransition={%s} openingApps=[%s] closingApps=[%s] transit=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/AppTransitionController.java"
- },
"-237664290": {
"message": "Pause the recording session on display %s",
"level": "VERBOSE",
@@ -1987,6 +1981,12 @@
"group": "WM_DEBUG_CONTENT_RECORDING",
"at": "com\/android\/server\/wm\/ContentRecorder.java"
},
+ "-134793542": {
+ "message": "handleAppTransitionReady: displayId=%d appTransition={%s} excludeLauncherFromAnimation=%b openingApps=[%s] closingApps=[%s] transit=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
"-134091882": {
"message": "Screenshotting Activity %s",
"level": "VERBOSE",
@@ -2491,12 +2491,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "323235828": {
- "message": "Delaying app transition for recents animation to finish",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/AppTransitionController.java"
- },
"327461496": {
"message": "Complete pause: %s",
"level": "VERBOSE",
diff --git a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
index 45b3066..9c195a7 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"نافذة ضمن النافذة"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ليس هناك عنوان للبرنامج)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"إغلاق"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"ملء الشاشة"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"نقل"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"توسيع"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"تصغير"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" انقر مرتين على "<annotation icon="home_icon">" الصفحة الرئيسية "</annotation>" للوصول لعناصر التحكم."</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"قائمة نافذة ضمن النافذة"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"نقل لليسار"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"نقل لليمين"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"نقل للأعلى"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"نقل للأسفل"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"تمّ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
index 91b9662..51a1262 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Ceo ekran"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Premesti"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Skupi"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" HOME "</annotation>" za kontrole"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni Slika u slici."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomerite nalevo"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomerite nadesno"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomerite nagore"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomerite nadole"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings_tv.xml b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
index 7ff6ce7..15a353c 100644
--- a/libs/WindowManager/Shell/res/values-be/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Відарыс у відарысе"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Праграма без назвы)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Закрыць"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Поўнаэкранны рэжым"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Перамясціць"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Разгарнуць"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Згарнуць"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Двойчы націсніце "<annotation icon="home_icon">" ГАЛОЎНЫ ЭКРАН "</annotation>" для пераходу ў налады"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню рэжыму \"Відарыс у відарысе\"."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Перамясціць улева"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Перамясціць управа"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Перамясціць уверх"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Перамясціць уніз"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Гатова"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
index c5dde15..2b27a69 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Картина в картината"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програма без заглавие)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Затваряне"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Цял екран"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Преместване"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Разгъване"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Свиване"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" За достъп до контролите натиснете 2 пъти "<annotation icon="home_icon">"НАЧАЛО"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню за функцията „Картина в картината“."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Преместване наляво"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Преместване надясно"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Преместване нагоре"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Преместване надолу"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
index 4005c7a..23c8ffa 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"ছবির-মধ্যে-ছবি"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(শিরোনামহীন প্রোগ্রাম)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"বন্ধ করুন"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"পূর্ণ স্ক্রিন"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"সরান"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"বড় করুন"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"আড়াল করুন"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" কন্ট্রোলের জন্য "<annotation icon="home_icon">" হোম "</annotation>" বোতামে ডবল প্রেস করুন"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ছবির-মধ্যে-ছবি মেনু।"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"বাঁদিকে সরান"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ডানদিকে সরান"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"উপরে তুলুন"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"নিচে নামান"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"হয়ে গেছে"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
index e2ea376..443fd62 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli ekran"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Premjesti"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Suzi"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" POČETNI EKRAN "</annotation>" za kontrole"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni za način rada slika u slici."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomjeranje ulijevo"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomjeranje udesno"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomjeranje nagore"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomjeranje nadolje"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
index 38cd35c..94ba0db 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla en pantalla"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sense títol)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Tanca"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Mou"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Desplega"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Replega"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Prem dos cops "<annotation icon="home_icon">" INICI "</annotation>" per accedir als controls"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla en pantalla."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mou cap a l\'esquerra"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mou cap a la dreta"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mou cap amunt"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mou cap avall"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Fet"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
index 4eeff00..3ed85dc 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Obraz v obraze"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Bez názvu)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zavřít"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Celá obrazovka"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Přesunout"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Rozbalit"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Sbalit"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Ovládací prvky zobrazíte dvojitým stisknutím "<annotation icon="home_icon">"tlačítka plochy"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Nabídka režimu obrazu v obraze"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Přesunout doleva"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Přesunout doprava"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Přesunout nahoru"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Přesunout dolů"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hotovo"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings_tv.xml b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
index f2ae12c..0902442 100644
--- a/libs/WindowManager/Shell/res/values-da/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Integreret billede"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program uden titel)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Luk"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Fuld skærm"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Flyt"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Udvid"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Skjul"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Tryk to gange på "<annotation icon="home_icon">" HJEM "</annotation>" for at se indstillinger"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu for integreret billede."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Flyt til venstre"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Flyt til højre"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Flyt op"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Flyt ned"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Udfør"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings_tv.xml b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
index 7ba693b..18535c9 100644
--- a/libs/WindowManager/Shell/res/values-de/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Bild im Bild"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Kein Sendungsname gefunden)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Schließen"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Vollbild"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Bewegen"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Maximieren"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Minimieren"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Für Steuerelemente zweimal "<annotation icon="home_icon">"STARTBILDSCHIRMTASTE"</annotation>" drücken"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menü „Bild im Bild“."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Nach links bewegen"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Nach rechts bewegen"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Nach oben bewegen"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Nach unten bewegen"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Fertig"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
index 187d41c..a2c27b7 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
@@ -25,7 +25,7 @@
<string name="pip_expand" msgid="1051966011679297308">"Expandir"</string>
<string name="pip_collapse" msgid="3903295106641385962">"Contraer"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Presiona dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string>
- <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de Pantalla en pantalla"</string>
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla en pantalla"</string>
<string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover hacia la izquierda"</string>
<string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover hacia la derecha"</string>
<string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover hacia arriba"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings_tv.xml b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
index d2fd0dc..7993e03 100644
--- a/libs/WindowManager/Shell/res/values-es/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Imagen en imagen"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sin título)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Cerrar"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Mover"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Mostrar"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Ocultar"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Pulsa dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de imagen en imagen."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover hacia la izquierda"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover hacia la derecha"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover hacia arriba"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover hacia abajo"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hecho"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings_tv.xml b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
index bcdacfb..e8fcb18 100644
--- a/libs/WindowManager/Shell/res/values-et/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pilt pildis"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programmi pealkiri puudub)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Sule"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Täisekraan"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Teisalda"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Laienda"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Ahenda"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Nuppude nägemiseks vajutage 2 korda nuppu "<annotation icon="home_icon">"AVAKUVA"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menüü Pilt pildis."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Teisalda vasakule"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Teisalda paremale"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Teisalda üles"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Teisalda alla"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Valmis"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
index 9cb1fa9..07d75d2 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantaila txiki gainjarria"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa izengabea)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Itxi"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pantaila osoa"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Mugitu"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Zabaldu"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Tolestu"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Kontrolatzeko aukerak atzitzeko, sakatu birritan "<annotation icon="home_icon">" HASIERA "</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Pantaila txiki gainjarriaren menua."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Eraman ezkerrera"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Eraman eskuinera"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Eraman gora"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Eraman behera"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Eginda"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
index e538004..24ab7d9 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Kuva kuvassa"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Nimetön)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Sulje"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Koko näyttö"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Siirrä"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Laajenna"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Tiivistä"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Asetukset: paina "<annotation icon="home_icon">"ALOITUSNÄYTTÖPAINIKETTA"</annotation>" kahdesti"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Kuva kuvassa ‑valikko."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Siirrä vasemmalle"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Siirrä oikealle"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Siirrä ylös"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Siirrä alas"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Valmis"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
index 2a6355f..87651ec 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Incrustation d\'image"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Aucun programme de titre)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Fermer"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Déplacer"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Développer"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Réduire"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Appuyez deux fois sur "<annotation icon="home_icon">" ACCUEIL "</annotation>" pour les commandes"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu d\'incrustation d\'image."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Déplacer vers la gauche"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Déplacer vers la droite"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Déplacer vers le haut"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Déplacer vers le bas"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"OK"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
index ac44d6e..37863fb 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programme sans titre)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Fermer"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Déplacer"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Développer"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Réduire"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Menu de commandes : appuyez deux fois sur "<annotation icon="home_icon">"ACCUEIL"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu \"Picture-in-picture\"."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Déplacer vers la gauche"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Déplacer vers la droite"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Déplacer vers le haut"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Déplacer vers le bas"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"OK"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
index d566226..5d6de76 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla superposta"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sen título)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Pechar"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Mover"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Despregar"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Contraer"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Preme "<annotation icon="home_icon">"INICIO"</annotation>" dúas veces para acceder aos controis"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla superposta."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover cara á esquerda"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover cara á dereita"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover cara arriba"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover cara abaixo"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Feito"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
index cc62d69..e022725 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"पिक्चर में पिक्चर"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(कोई शीर्षक कार्यक्रम नहीं)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"बंद करें"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"फ़ुल स्क्रीन"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ले जाएं"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"बड़ा करें"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"छोटा करें"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" कंट्रोल मेन्यू पर जाने के लिए, "<annotation icon="home_icon">" होम बटन"</annotation>" दो बार दबाएं"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"पिक्चर में पिक्चर मेन्यू."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"बाईं ओर ले जाएं"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"दाईं ओर ले जाएं"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ऊपर ले जाएं"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"नीचे ले जाएं"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"हो गया"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
index 42eb1ee..a09e6e8 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli zaslon"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Premjesti"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Sažmi"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">"POČETNI ZASLON"</annotation>" za kontrole"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Izbornik slike u slici."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomaknite ulijevo"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomaknite udesno"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomaknite prema gore"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomaknite prema dolje"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
index 0a0892b..7963abf 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Նկար նկարի մեջ"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Առանց վերնագրի ծրագիր)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Փակել"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Լիէկրան"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Տեղափոխել"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Ծավալել"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Ծալել"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Կարգավորումների համար կրկնակի սեղմեք "<annotation icon="home_icon">"ԳԼԽԱՎՈՐ ԷԿՐԱՆ"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"«Նկար նկարի մեջ» ռեժիմի ընտրացանկ։"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Տեղափոխել ձախ"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Տեղափոխել աջ"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Տեղափոխել վերև"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Տեղափոխել ներքև"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Պատրաստ է"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings_tv.xml b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
index b04fee847a..7d37154 100644
--- a/libs/WindowManager/Shell/res/values-in/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program tanpa judul)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Tutup"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Layar penuh"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Pindahkan"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Luaskan"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Ciutkan"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Tekan dua kali "<annotation icon="home_icon">" HOME "</annotation>" untuk membuka kontrol"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu Picture-in-Picture."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pindahkan ke kiri"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pindahkan ke kanan"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pindahkan ke atas"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pindahkan ke bawah"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Selesai"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings_tv.xml b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
index 661832a..1490cb9 100644
--- a/libs/WindowManager/Shell/res/values-is/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Mynd í mynd"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Efni án titils)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Loka"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Allur skjárinn"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Færa"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Stækka"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Minnka"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Ýttu tvisvar á "<annotation icon="home_icon">" HEIM "</annotation>" til að opna stillingar"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Valmynd fyrir mynd í mynd."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Færa til vinstri"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Færa til hægri"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Færa upp"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Færa niður"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Lokið"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings_tv.xml b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
index a2911d3..1a7ae81 100644
--- a/libs/WindowManager/Shell/res/values-km/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"រូបក្នុងរូប"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(កម្មវិធីគ្មានចំណងជើង)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"បិទ"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"ពេញអេក្រង់"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ផ្លាស់ទី"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ពង្រីក"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"បង្រួម"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" ចុចពីរដងលើ"<annotation icon="home_icon">"ប៊ូតុងដើម"</annotation>" ដើម្បីបើកផ្ទាំងគ្រប់គ្រង"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ម៉ឺនុយរូបក្នុងរូប"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ផ្លាស់ទីទៅឆ្វេង"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ផ្លាស់ទីទៅស្តាំ"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ផ្លាស់ទីឡើងលើ"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ផ្លាស់ទីចុះក្រោម"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"រួចរាល់"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
index 2f0bf96..45de068 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ಶೀರ್ಷಿಕೆ ರಹಿತ ಕಾರ್ಯಕ್ರಮ)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"ಮುಚ್ಚಿರಿ"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"ಪೂರ್ಣ ಪರದೆ"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ಸರಿಸಿ"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"ಕುಗ್ಗಿಸಿ"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" ಕಂಟ್ರೋಲ್ಗಳಿಗಾಗಿ "<annotation icon="home_icon">" ಹೋಮ್ "</annotation>" ಅನ್ನು ಎರಡು ಬಾರಿ ಒತ್ತಿ"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ ಮೆನು."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ಕೆಳಗೆ ಸರಿಸಿ"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ಮುಗಿದಿದೆ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
index e2aa7dc..9e8f1f1 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"PIP 모드"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(제목 없는 프로그램)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"닫기"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"전체화면"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"이동"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"펼치기"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"접기"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" 제어 메뉴에 액세스하려면 "<annotation icon="home_icon">" 홈 "</annotation>"을 두 번 누르세요."</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"PIP 모드 메뉴입니다."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"왼쪽으로 이동"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"오른쪽으로 이동"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"위로 이동"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"아래로 이동"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"완료"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
index 706641a..19fac58 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Сүрөттөгү сүрөт"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Аталышы жок программа)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Жабуу"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Толук экран"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Жылдыруу"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Жайып көрсөтүү"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Жыйыштыруу"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Башкаруу элементтерин ачуу үчүн "<annotation icon="home_icon">" БАШКЫ БЕТ "</annotation>" баскычын эки жолу басыңыз"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Сүрөт ичиндеги сүрөт менюсу."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Солго жылдыруу"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Оңго жылдыруу"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Жогору жылдыруу"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Төмөн жылдыруу"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Бүттү"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
index d75453f..6cd0f37 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"ການສະແດງຜົນຊ້ອນກັນ"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ໂປຣແກຣມບໍ່ມີຊື່)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"ປິດ"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"ເຕັມໜ້າຈໍ"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ຍ້າຍ"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ຂະຫຍາຍ"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"ຫຍໍ້"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" ກົດ "<annotation icon="home_icon">" HOME "</annotation>" ສອງເທື່ອສຳລັບການຄວບຄຸມ"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ເມນູການສະແດງຜົນຊ້ອນກັນ."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ຍ້າຍໄປຊ້າຍ"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ຍ້າຍໄປຂວາ"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ຍ້າຍຂຶ້ນ"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ຍ້າຍລົງ"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ແລ້ວໆ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
index d0e017e..11abac6 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Attēls attēlā"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programma bez nosaukuma)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Aizvērt"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pilnekrāna režīms"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Pārvietot"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Izvērst"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Sakļaut"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Atvērt vadīklas: divreiz nospiediet pogu "<annotation icon="home_icon">"SĀKUMS"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Izvēlne attēlam attēlā."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pārvietot pa kreisi"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pārvietot pa labi"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pārvietot augšup"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pārvietot lejup"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gatavs"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings_tv.xml b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
index 04d2741..105628d 100644
--- a/libs/WindowManager/Shell/res/values-my/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"နှစ်ခုထပ်၍ကြည့်ခြင်း"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ခေါင်းစဉ်မဲ့ အစီအစဉ်)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"ပိတ်ရန်"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"မျက်နှာပြင် အပြည့်"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ရွှေ့ရန်"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ချဲ့ရန်"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"လျှော့ပြရန်"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" ထိန်းချုပ်မှုအတွက် "<annotation icon="home_icon">" ပင်မခလုတ် "</annotation>" နှစ်ချက်နှိပ်ပါ"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"နှစ်ခုထပ်၍ ကြည့်ခြင်းမီနူး။"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ဘယ်သို့ရွှေ့ရန်"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ညာသို့ရွှေ့ရန်"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"အပေါ်သို့ရွှေ့ရန်"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"အောက်သို့ရွှေ့ရန်"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ပြီးပြီ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
index ed135c5..ca63518 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Bilde-i-bilde"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program uten tittel)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Lukk"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Fullskjerm"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Flytt"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Vis"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Skjul"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Dobbelttrykk på "<annotation icon="home_icon">"HJEM"</annotation>" for å åpne kontroller"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Bilde-i-bilde-meny."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Flytt til venstre"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Flytt til høyre"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Flytt opp"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Flytt ned"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Ferdig"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings_tv.xml b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
index bf86592..0c1d99e 100644
--- a/libs/WindowManager/Shell/res/values-or/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"ପିକଚର୍-ଇନ୍-ପିକଚର୍"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(କୌଣସି ଟାଇଟଲ୍ ପ୍ରୋଗ୍ରାମ୍ ନାହିଁ)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ମୁଭ କରନ୍ତୁ"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ବିସ୍ତାର କରନ୍ତୁ"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ପାଇଁ "<annotation icon="home_icon">" ହୋମ ବଟନ "</annotation>"କୁ ଦୁଇଥର ଦବାନ୍ତୁ"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ପିକଚର-ଇନ-ପିକଚର ମେନୁ।"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ବାମକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ତଳକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ହୋଇଗଲା"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
index d024e13..2bb90ad 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Obraz w obrazie"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez tytułu)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zamknij"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Pełny ekran"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Przenieś"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Rozwiń"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Zwiń"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Naciśnij dwukrotnie "<annotation icon="home_icon">"EKRAN GŁÓWNY"</annotation>", aby wyświetlić ustawienia"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu funkcji Obraz w obrazie."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Przenieś w lewo"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Przenieś w prawo"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Przenieś w górę"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Przenieś w dół"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotowe"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
index 16331a6..88fc832 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika v sliki"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program brez naslova)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Zapri"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Celozaslonsko"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Premakni"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Razširi"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Strni"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Za kontrolnike dvakrat pritisnite gumb za "<annotation icon="home_icon">" ZAČETNI ZASLON "</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni za sliko v sliki"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Premakni levo"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Premakni desno"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Premakni navzgor"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Premakni navzdol"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Končano"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
index a229d2d..58687e5 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Figurë brenda figurës"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program pa titull)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Mbyll"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Ekrani i plotë"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Lëviz"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Zgjero"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Palos"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Trokit dy herë "<annotation icon="home_icon">" KREU "</annotation>" për kontrollet"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menyja e \"Figurës brenda figurës\"."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Lëviz majtas"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Lëviz djathtas"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Lëviz lart"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Lëviz poshtë"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"U krye"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
index 7491876..e850979 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Слика у слици"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програм без наслова)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Затвори"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"Цео екран"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Премести"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Прошири"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Скупи"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Двапут притисните "<annotation icon="home_icon">" HOME "</annotation>" за контроле"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Мени Слика у слици."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Померите налево"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Померите надесно"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Померите нагоре"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Померите надоле"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings_tv.xml b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
index f379fad..27cf56c 100644
--- a/libs/WindowManager/Shell/res/values-th/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"การแสดงภาพซ้อนภาพ"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ไม่มีชื่อรายการ)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"ปิด"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"เต็มหน้าจอ"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"ย้าย"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"ขยาย"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"ยุบ"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" กดปุ่ม "<annotation icon="home_icon">" หน้าแรก "</annotation>" สองครั้งเพื่อเปิดการควบคุม"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"เมนูการแสดงภาพซ้อนภาพ"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ย้ายไปทางซ้าย"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ย้ายไปทางขวา"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ย้ายขึ้น"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ย้ายลง"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"เสร็จ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
index 579d7ae..69bb608 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
@@ -24,7 +24,7 @@
<string name="pip_move" msgid="158770205886688553">"Taşı"</string>
<string name="pip_expand" msgid="1051966011679297308">"Genişlet"</string>
<string name="pip_collapse" msgid="3903295106641385962">"Daralt"</string>
- <string name="pip_edu_text" msgid="3672999496647508701">" Kontroller için "<annotation icon="home_icon">" ANA SAYFA "</annotation>"\'ya iki kez basın"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Kontroller için "<annotation icon="home_icon">" ANA SAYFA "</annotation>" düğmesine iki kez basın"</string>
<string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Pencere içinde pencere menüsü."</string>
<string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Sola taşı"</string>
<string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Sağa taşı"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
index 4b2d9df..81a8285c 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"Картинка в картинці"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програма без назви)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"Закрити"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"На весь екран"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"Перемістити"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Розгорнути"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Згорнути"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" Відкрити елементи керування: двічі натисніть "<annotation icon="home_icon">"HOME"</annotation></string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню \"картинка в картинці\""</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Перемістити ліворуч"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Перемістити праворуч"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Перемістити вгору"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Перемістити вниз"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
index e3292a1..acbc26d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"畫中畫"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(沒有標題的節目)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"關閉"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"移動"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"展開"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"收合"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">" 主畫面按鈕"</annotation>"即可顯示控制項"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"畫中畫選單。"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"向左移"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"向右移"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"向上移"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"向下移"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完成"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
index f670e3a..f8c683e 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
@@ -19,26 +19,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"子母畫面"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(無標題的節目)"</string>
- <!-- no translation found for pip_close (2955969519031223530) -->
- <skip />
+ <string name="pip_close" msgid="2955969519031223530">"關閉"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string>
- <!-- no translation found for pip_move (158770205886688553) -->
- <skip />
- <!-- no translation found for pip_expand (1051966011679297308) -->
- <skip />
- <!-- no translation found for pip_collapse (3903295106641385962) -->
- <skip />
+ <string name="pip_move" msgid="158770205886688553">"移動"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"展開"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"收合"</string>
<string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">"主畫面按鈕"</annotation>"即可顯示控制選項"</string>
- <!-- no translation found for a11y_pip_menu_entered (5106343214776801614) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_left (6612980937817141583) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_right (1119409122645529936) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_up (98502616918621959) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_down (3858802832725159740) -->
- <skip />
- <!-- no translation found for a11y_action_pip_move_done (1486845365134416210) -->
- <skip />
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"子母畫面選單。"</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"向左移動"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"向右移動"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"向上移動"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"向下移動"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完成"</string>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index bf074b0..9230c22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -145,6 +145,8 @@
}
mDisplayAreasInfo.remove(displayId);
+ mLeashes.get(displayId).release();
+ mLeashes.remove(displayId);
ArrayList<RootTaskDisplayAreaListener> listeners = mListeners.get(displayId);
if (listeners != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index a089585..b8bf1a8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -706,6 +706,8 @@
* @param animate whether the pointer should animate to this position.
*/
public void setPointerPosition(float bubblePosition, boolean onLeft, boolean animate) {
+ final boolean isRtl = mContext.getResources().getConfiguration().getLayoutDirection()
+ == LAYOUT_DIRECTION_RTL;
// Pointer gets drawn in the padding
final boolean showVertically = mPositioner.showBubblesVertically();
final float paddingLeft = (showVertically && onLeft)
@@ -732,12 +734,22 @@
float pointerX;
if (showVertically) {
pointerY = bubbleCenter - (mPointerWidth / 2f);
- pointerX = onLeft
- ? -mPointerHeight + mPointerOverlap
- : getWidth() - mPaddingRight - mPointerOverlap;
+ if (!isRtl) {
+ pointerX = onLeft
+ ? -mPointerHeight + mPointerOverlap
+ : getWidth() - mPaddingRight - mPointerOverlap;
+ } else {
+ pointerX = onLeft
+ ? -(getWidth() - mPaddingLeft - mPointerOverlap)
+ : mPointerHeight - mPointerOverlap;
+ }
} else {
pointerY = mPointerOverlap;
- pointerX = bubbleCenter - (mPointerWidth / 2f);
+ if (!isRtl) {
+ pointerX = bubbleCenter - (mPointerWidth / 2f);
+ } else {
+ pointerX = -(getWidth() - mPaddingLeft - bubbleCenter) + (mPointerWidth / 2f);
+ }
}
if (animate) {
mPointerView.animate().translationX(pointerX).translationY(pointerY).start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index c05654a..e624de6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1600,6 +1600,11 @@
// Avoid double removal, which is fatal.
return;
}
+ if (surface == null || !surface.isValid()) {
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: trying to remove invalid content overlay (%s)", TAG, surface);
+ return;
+ }
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
tx.remove(surface);
tx.apply();
diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp
index fecf269..8191f5e 100644
--- a/libs/hwui/FrameInfo.cpp
+++ b/libs/hwui/FrameInfo.cpp
@@ -20,19 +20,33 @@
namespace android {
namespace uirenderer {
-const std::array FrameInfoNames{
- "Flags", "FrameTimelineVsyncId", "IntendedVsync",
- "Vsync", "InputEventId", "HandleInputStart",
- "AnimationStart", "PerformTraversalsStart", "DrawStart",
- "FrameDeadline", "FrameInterval", "FrameStartTime",
- "SyncQueued", "SyncStart", "IssueDrawCommandsStart",
- "SwapBuffers", "FrameCompleted", "DequeueBufferDuration",
- "QueueBufferDuration", "GpuCompleted", "SwapBuffersCompleted",
- "DisplayPresentTime",
+const std::array FrameInfoNames{"Flags",
+ "FrameTimelineVsyncId",
+ "IntendedVsync",
+ "Vsync",
+ "InputEventId",
+ "HandleInputStart",
+ "AnimationStart",
+ "PerformTraversalsStart",
+ "DrawStart",
+ "FrameDeadline",
+ "FrameInterval",
+ "FrameStartTime",
+ "SyncQueued",
+ "SyncStart",
+ "IssueDrawCommandsStart",
+ "SwapBuffers",
+ "FrameCompleted",
+ "DequeueBufferDuration",
+ "QueueBufferDuration",
+ "GpuCompleted",
+ "SwapBuffersCompleted",
+ "DisplayPresentTime",
+ "CommandSubmissionCompleted"
};
-static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 22,
+static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 23,
"Must update value in FrameMetrics.java#FRAME_STATS_COUNT (and here)");
void FrameInfo::importUiThreadInfo(int64_t* info) {
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index 540a88b..564ee4f 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -58,6 +58,7 @@
GpuCompleted,
SwapBuffersCompleted,
DisplayPresentTime,
+ CommandSubmissionCompleted,
// Must be the last value!
// Also must be kept in sync with FrameMetrics.java#FRAME_STATS_COUNT
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 744739a..2aca41e 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -16,8 +16,15 @@
#include "SkiaOpenGLPipeline.h"
+#include <GrBackendSurface.h>
+#include <SkBlendMode.h>
+#include <SkImageInfo.h>
+#include <cutils/properties.h>
#include <gui/TraceUtils.h>
+#include <strings.h>
+
#include "DeferredLayerUpdater.h"
+#include "FrameInfo.h"
#include "LayerDrawable.h"
#include "LightingInfo.h"
#include "SkiaPipeline.h"
@@ -27,17 +34,9 @@
#include "renderstate/RenderState.h"
#include "renderthread/EglManager.h"
#include "renderthread/Frame.h"
+#include "renderthread/IRenderPipeline.h"
#include "utils/GLUtils.h"
-#include <GLES3/gl3.h>
-
-#include <GrBackendSurface.h>
-#include <SkBlendMode.h>
-#include <SkImageInfo.h>
-
-#include <cutils/properties.h>
-#include <strings.h>
-
using namespace android::uirenderer::renderthread;
namespace android {
@@ -69,12 +68,11 @@
return mEglManager.beginFrame(mEglSurface);
}
-bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
- const LightGeometry& lightGeometry,
- LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
- bool opaque, const LightInfo& lightInfo,
- const std::vector<sp<RenderNode>>& renderNodes,
- FrameInfoVisualizer* profiler) {
+IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw(
+ const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+ const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+ const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+ const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) {
if (!isCapturingSkp()) {
mEglManager.damageFrame(frame, dirty);
}
@@ -129,7 +127,7 @@
dumpResourceCacheUsage();
}
- return true;
+ return {true, IRenderPipeline::DrawResult::kUnknownTime};
}
bool SkiaOpenGLPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index fddd97f..186998a 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -36,11 +36,14 @@
renderthread::MakeCurrentResult makeCurrent() override;
renderthread::Frame getFrame() override;
- bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
- const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
- const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
- const std::vector<sp<RenderNode> >& renderNodes,
- FrameInfoVisualizer* profiler) override;
+ renderthread::IRenderPipeline::DrawResult draw(const renderthread::Frame& frame,
+ const SkRect& screenDirty, const SkRect& dirty,
+ const LightGeometry& lightGeometry,
+ LayerUpdateQueue* layerUpdateQueue,
+ const Rect& contentDrawBounds, bool opaque,
+ const LightInfo& lightInfo,
+ const std::vector<sp<RenderNode> >& renderNodes,
+ FrameInfoVisualizer* profiler) override;
GrSurfaceOrigin getSurfaceOrigin() override { return kBottomLeft_GrSurfaceOrigin; }
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 99fd463..905d46e 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -16,7 +16,15 @@
#include "SkiaVulkanPipeline.h"
+#include <GrDirectContext.h>
+#include <GrTypes.h>
+#include <SkSurface.h>
+#include <SkTypes.h>
+#include <cutils/properties.h>
#include <gui/TraceUtils.h>
+#include <strings.h>
+#include <vk/GrVkTypes.h>
+
#include "DeferredLayerUpdater.h"
#include "LightingInfo.h"
#include "Readback.h"
@@ -26,16 +34,7 @@
#include "VkInteropFunctorDrawable.h"
#include "renderstate/RenderState.h"
#include "renderthread/Frame.h"
-
-#include <SkSurface.h>
-#include <SkTypes.h>
-
-#include <GrDirectContext.h>
-#include <GrTypes.h>
-#include <vk/GrVkTypes.h>
-
-#include <cutils/properties.h>
-#include <strings.h>
+#include "renderthread/IRenderPipeline.h"
using namespace android::uirenderer::renderthread;
@@ -64,15 +63,14 @@
return vulkanManager().dequeueNextBuffer(mVkSurface);
}
-bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
- const LightGeometry& lightGeometry,
- LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
- bool opaque, const LightInfo& lightInfo,
- const std::vector<sp<RenderNode>>& renderNodes,
- FrameInfoVisualizer* profiler) {
+IRenderPipeline::DrawResult SkiaVulkanPipeline::draw(
+ const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+ const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+ const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+ const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) {
sk_sp<SkSurface> backBuffer = mVkSurface->getCurrentSkSurface();
if (backBuffer.get() == nullptr) {
- return false;
+ return {false, -1};
}
// update the coordinates of the global light position based on surface rotation
@@ -94,9 +92,10 @@
profiler->draw(profileRenderer);
}
+ nsecs_t submissionTime = IRenderPipeline::DrawResult::kUnknownTime;
{
ATRACE_NAME("flush commands");
- vulkanManager().finishFrame(backBuffer.get());
+ submissionTime = vulkanManager().finishFrame(backBuffer.get());
}
layerUpdateQueue->clear();
@@ -105,7 +104,7 @@
dumpResourceCacheUsage();
}
- return true;
+ return {true, submissionTime};
}
bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 56d42e0..ada6af6 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -33,11 +33,14 @@
renderthread::MakeCurrentResult makeCurrent() override;
renderthread::Frame getFrame() override;
- bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
- const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
- const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
- const std::vector<sp<RenderNode> >& renderNodes,
- FrameInfoVisualizer* profiler) override;
+ renderthread::IRenderPipeline::DrawResult draw(const renderthread::Frame& frame,
+ const SkRect& screenDirty, const SkRect& dirty,
+ const LightGeometry& lightGeometry,
+ LayerUpdateQueue* layerUpdateQueue,
+ const Rect& contentDrawBounds, bool opaque,
+ const LightInfo& lightInfo,
+ const std::vector<sp<RenderNode> >& renderNodes,
+ FrameInfoVisualizer* profiler) override;
GrSurfaceOrigin getSurfaceOrigin() override { return kTopLeft_GrSurfaceOrigin; }
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 122c77f..976117b 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -512,9 +512,9 @@
ATRACE_FORMAT("Drawing " RECT_STRING, SK_RECT_ARGS(dirty));
- bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
- mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
- &(profiler()));
+ const auto drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry,
+ &mLayerUpdateQueue, mContentDrawBounds, mOpaque,
+ mLightInfo, mRenderNodes, &(profiler()));
uint64_t frameCompleteNr = getFrameNumber();
@@ -534,8 +534,11 @@
bool requireSwap = false;
int error = OK;
- bool didSwap =
- mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
+ bool didSwap = mRenderPipeline->swapBuffers(frame, drawResult.success, windowDirty,
+ mCurrentFrameInfo, &requireSwap);
+
+ mCurrentFrameInfo->set(FrameInfoIndex::CommandSubmissionCompleted) = std::max(
+ drawResult.commandSubmissionTime, mCurrentFrameInfo->get(FrameInfoIndex::SwapBuffers));
mIsDirty = false;
@@ -753,7 +756,8 @@
if (frameInfo != nullptr) {
frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
- frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
+ frameInfo->set(FrameInfoIndex::GpuCompleted) = std::max(
+ gpuCompleteTime, frameInfo->get(FrameInfoIndex::CommandSubmissionCompleted));
std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter, frameNumber,
surfaceControlId);
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index aceb5a5..ef58bc5 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -49,11 +49,21 @@
public:
virtual MakeCurrentResult makeCurrent() = 0;
virtual Frame getFrame() = 0;
- virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
- const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
- const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
- const std::vector<sp<RenderNode>>& renderNodes,
- FrameInfoVisualizer* profiler) = 0;
+
+ // Result of IRenderPipeline::draw
+ struct DrawResult {
+ // True if draw() succeeded, false otherwise
+ bool success = false;
+ // If drawing was successful, reports the time at which command
+ // submission occurred. -1 if this time is unknown.
+ static constexpr nsecs_t kUnknownTime = -1;
+ nsecs_t commandSubmissionTime = kUnknownTime;
+ };
+ virtual DrawResult draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+ const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+ const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+ const std::vector<sp<RenderNode>>& renderNodes,
+ FrameInfoVisualizer* profiler) = 0;
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index a9ff2c6..718d4a1 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -494,7 +494,7 @@
}
}
-void VulkanManager::finishFrame(SkSurface* surface) {
+nsecs_t VulkanManager::finishFrame(SkSurface* surface) {
ATRACE_NAME("Vulkan finish frame");
ALOGE_IF(mSwapSemaphore != VK_NULL_HANDLE || mDestroySemaphoreContext != nullptr,
"finishFrame already has an outstanding semaphore");
@@ -530,6 +530,7 @@
GrDirectContext* context = GrAsDirectContext(surface->recordingContext());
ALOGE_IF(!context, "Surface is not backed by gpu");
context->submit();
+ const nsecs_t submissionTime = systemTime();
if (semaphore != VK_NULL_HANDLE) {
if (submitted == GrSemaphoresSubmitted::kYes) {
mSwapSemaphore = semaphore;
@@ -558,6 +559,8 @@
}
}
skiapipeline::ShaderCache::get().onVkFrameFlushed(context);
+
+ return submissionTime;
}
void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) {
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index b816649..b8c2bdf 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -84,7 +84,9 @@
void destroySurface(VulkanSurface* surface);
Frame dequeueNextBuffer(VulkanSurface* surface);
- void finishFrame(SkSurface* surface);
+ // Finishes the frame and submits work to the GPU
+ // Returns the estimated start time for intiating GPU work, -1 otherwise.
+ nsecs_t finishFrame(SkSurface* surface);
void swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect);
// Inserts a wait on fence command into the Vulkan command buffer.
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index fc449d5..3d35e55 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -38,8 +38,8 @@
<string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
- <string name="consent_yes" msgid="8344487259618762872">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
- <string name="consent_no" msgid="2640796915611404382">"ਇਜਾਜ਼ਤ ਨਾ ਦਿਓ"</string>
+ <string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
+ <string name="consent_no" msgid="2640796915611404382">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
<string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ਐਪ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਆਪਣੀ ਘੜੀ \'ਤੇ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰੋ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ਤੁਹਾਡੀ ਘੜੀ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨਾ ਆਸਾਨ ਬਣਾਉਣ ਲਈ, ਤੁਹਾਡੀ ਘੜੀ \'ਤੇ ਸਥਾਪਤ ਐਪਾਂ ਸੈੱਟਅੱਪ ਦੌਰਾਨ ਉਹੀ ਇਜਾਜ਼ਤਾਂ ਵਰਤਣਗੀਆਂ ਜੋ ਤੁਹਾਡਾ ਫ਼ੋਨ ਵਰਤਦਾ ਹੈ।\n\n ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਘੜੀ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
diff --git a/packages/EasterEgg/res/drawable/android_13.xml b/packages/EasterEgg/res/drawable/android_13.xml
new file mode 100644
index 0000000..edc44ce
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android_13.xml
@@ -0,0 +1,42 @@
+<!--
+Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="1.56"
+ android:strokeColor="@android:color/system_neutral1_100"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="1.56"
+ android:strokeColor="@android:color/system_neutral1_100"
+ />
+
+</vector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/drawable/android_13_mono.xml b/packages/EasterEgg/res/drawable/android_13_mono.xml
new file mode 100644
index 0000000..55c1bcd
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android_13_mono.xml
@@ -0,0 +1,31 @@
+<!--
+Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+</vector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/drawable/icon.xml b/packages/EasterEgg/res/drawable/icon.xml
index 7054962..cdac1f9 100644
--- a/packages/EasterEgg/res/drawable/icon.xml
+++ b/packages/EasterEgg/res/drawable/icon.xml
@@ -15,5 +15,6 @@
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_bg"/>
- <foreground android:drawable="@drawable/android_s"/>
+ <foreground android:drawable="@drawable/android_13"/>
+ <monochrome android:drawable="@drawable/android_13_mono"/>
</adaptive-icon>
diff --git a/packages/EasterEgg/res/drawable/icon_bg.xml b/packages/EasterEgg/res/drawable/icon_bg.xml
index d08e160..231b4b8 100644
--- a/packages/EasterEgg/res/drawable/icon_bg.xml
+++ b/packages/EasterEgg/res/drawable/icon_bg.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<color xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@android:color/system_accent2_500" />
+ android:color="@android:color/system_accent3_400" />
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index 8ddc87c..e2a5aaa 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -84,9 +84,9 @@
<string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"セキュリティ上の理由から、お使いのタブレットでは現在、この提供元からの不明なアプリをインストールすることはできません。これは [設定] で変更できます。"</string>
<string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"セキュリティ上の理由から、お使いのテレビでは現在、この提供元からの不明なアプリをインストールすることはできません。これは [設定] で変更できます。"</string>
<string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"セキュリティ上の理由から、お使いのスマートフォンでは現在、この提供元からの不明なアプリをインストールすることはできません。これは [設定] で変更できます。"</string>
- <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"不明なアプリをインストールするとスマートフォンや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるスマートフォンへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"不明なアプリをインストールするとタブレットや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるタブレットへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"不明なアプリをインストールするとテレビや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるテレビへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+ <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"不明なアプリをインストールするとスマートフォンや個人データの侵害に対する安全性が低下します。このアプリをインストールすることで、アプリの使用により生じる可能性があるスマートフォンへの侵害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意することになります。"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"不明なアプリをインストールするとタブレットや個人データの侵害に対する安全性が低下します。このアプリをインストールすることで、アプリの使用により生じる可能性があるタブレットへの侵害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意することになります。"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"不明なアプリをインストールするとテレビや個人データの侵害に対する安全性が低下します。このアプリをインストールすることで、アプリの使用により生じる可能性があるテレビへの侵害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意することになります。"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"次へ"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"設定"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Wearアプリ インストール/アンインストール"</string>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index 17a0e82..50422d7 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -21,8 +21,8 @@
<string name="update" msgid="3932142540719227615">"अपडेट गर्नुहोस्"</string>
<string name="done" msgid="6632441120016885253">"सम्पन्न भयो"</string>
<string name="cancel" msgid="1018267193425558088">"रद्द गर्नुहोस्"</string>
- <string name="installing" msgid="4921993079741206516">"स्थापना गर्दै…"</string>
- <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string>
+ <string name="installing" msgid="4921993079741206516">"इन्स्टल गरिँदै छ"</string>
+ <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इन्स्टल गरिँदै छ"</string>
<string name="install_done" msgid="5987363587661783896">"एप इन्स्टल गरियो।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"तपाईं यो एप इन्स्टल गर्न चाहनुहुन्छ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"तपाईं यो एप अपडेट गर्न चाहनुहुन्छ?"</string>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index d5b8573..05bf127 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -83,7 +83,7 @@
<string name="app_name_unknown" msgid="6881210203354323926">"ਅਗਿਆਤ"</string>
<string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
<string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ ਟੀਵੀ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
- <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹੋਣ ਵਾਲੇ ਹਮਲਿਆਂ ਕਰਕੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਨਿੱਜੀ ਡਾਟੇ ਨਾਲ ਛੇੜਛਾੜ ਹੋ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ੁੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ਤੁਹਾਡਾ ਟੀਵੀ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੀਵੀ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ੁੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
diff --git a/packages/SystemUI/res/drawable-nodpi/android_13.xml b/packages/SystemUI/res/drawable-nodpi/android_13.xml
new file mode 100644
index 0000000..edc44ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/android_13.xml
@@ -0,0 +1,42 @@
+<!--
+Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="1.56"
+ android:strokeColor="@android:color/system_neutral1_100"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="1.56"
+ android:strokeColor="@android:color/system_neutral1_100"
+ />
+
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable-nodpi/android_13_mono.xml b/packages/SystemUI/res/drawable-nodpi/android_13_mono.xml
new file mode 100644
index 0000000..55c1bcd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/android_13_mono.xml
@@ -0,0 +1,31 @@
+<!--
+Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M37,39.03l8.58,0l0,33.94"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+ <path
+ android:pathData="M53.98,39.03h11.31l-5.59,11.31c6.02,0.96 10.11,6.62 9.15,12.64c-0.85,5.3 -5.38,9.22 -10.74,9.29c-1.38,-0 -2.76,-0.26 -4.05,-0.75"
+ android:strokeWidth="6.2"
+ android:strokeColor="@android:color/system_accent1_800"
+ />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml
index 9972496..cdac1f9 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon.xml
@@ -15,5 +15,6 @@
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_bg"/>
- <foreground android:drawable="@drawable/android_12"/>
+ <foreground android:drawable="@drawable/android_13"/>
+ <monochrome android:drawable="@drawable/android_13_mono"/>
</adaptive-icon>
diff --git a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
index f7b0982..231b4b8 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<color xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/material_dynamic_primary50" />
+ android:color="@android:color/system_accent3_400" />
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index 18f870d..3d78489 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -24,6 +24,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginStart="4dp"
+ android:textColor="?android:attr/textColorSecondary"
app:layout_constraintStart_toStartOf="@id/done_button"
app:layout_constraintTop_toBottomOf="@id/done_button" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1dd41a3..99f4c76 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2477,7 +2477,7 @@
<!-- Title for dialog listing applications currently running [CHAR LIMIT=NONE]-->
<string name="fgs_manager_dialog_title">Active apps</string>
<!-- Detailed message for dialog listing applications currently running [CHAR LIMIT=NONE]-->
- <string name="fgs_manager_dialog_message">Even if you\u2019re not using these apps, they\u2019re still active and might affect battery life</string>
+ <string name="fgs_manager_dialog_message">These apps are active and running, even when you\u2019re not using them. This improves their functionality, but it may also affect battery life.</string>
<!-- Label of the button to stop an app from running [CHAR LIMIT=12]-->
<string name="fgs_manager_app_item_stop_button_label">Stop</string>
<!-- Label of the button to stop an app from running but the app is already stopped and the button is disabled [CHAR LIMIT=12]-->
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index b54b832..570d11b 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PersistableBundle;
+import android.text.Editable;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
@@ -93,7 +94,9 @@
}
private void saveToClipboard() {
- ClipData clip = ClipData.newPlainText("text", mEditText.getText());
+ Editable editedText = mEditText.getText();
+ editedText.clearSpans();
+ ClipData clip = ClipData.newPlainText("text", editedText);
PersistableBundle extras = new PersistableBundle();
extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, mSensitive);
clip.getDescription().setExtras(extras);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 8d2b14a..80eacd1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -44,6 +44,7 @@
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_FOOTER_DOT
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.animation.DialogLaunchAnimator
@@ -81,6 +82,8 @@
companion object {
private val LOG_TAG = FgsManagerController::class.java.simpleName
+ private const val DEFAULT_TASK_MANAGER_ENABLED = true
+ private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
}
var changesSinceDialog = false
@@ -88,6 +91,8 @@
var isAvailable = false
private set
+ var showFooterDot = false
+ private set
private val lock = Any()
@@ -151,10 +156,14 @@
deviceConfigProxy.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI,
backgroundExecutor) {
isAvailable = it.getBoolean(TASK_MANAGER_ENABLED, isAvailable)
+ showFooterDot =
+ it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
}
- isAvailable = deviceConfigProxy
- .getBoolean(NAMESPACE_SYSTEMUI, TASK_MANAGER_ENABLED, true)
+ isAvailable = deviceConfigProxy.getBoolean(NAMESPACE_SYSTEMUI,
+ TASK_MANAGER_ENABLED, DEFAULT_TASK_MANAGER_ENABLED)
+ showFooterDot = deviceConfigProxy.getBoolean(NAMESPACE_SYSTEMUI,
+ TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT)
dumpManager.registerDumpable(this)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
index abebf3e..ba6b1dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
@@ -149,8 +149,8 @@
if (mFgsManagerController.shouldUpdateFooterVisibility()) {
mRootView.setVisibility(mNumPackages > 0
&& mFgsManagerController.isAvailable() ? View.VISIBLE : View.GONE);
- int dotVis =
- mFgsManagerController.getChangesSinceDialog() ? View.VISIBLE : View.GONE;
+ int dotVis = mFgsManagerController.getShowFooterDot()
+ && mFgsManagerController.getChangesSinceDialog() ? View.VISIBLE : View.GONE;
mDotView.setVisibility(dotVis);
mCollapsedDotView.setVisibility(dotVis);
if (mVisibilityChangedListener != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 6287857..22234b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -58,7 +58,7 @@
private var maxKeyguardNotifications by notNull<Int>()
/** Minimum space between two notifications, see [calculateGapAndDividerHeight]. */
- private var dividerHeight by notNull<Int>()
+ private var dividerHeight by notNull<Float>()
init {
updateResources()
@@ -142,9 +142,13 @@
if (i == children.lastIndex) {
0f // No shelf needed.
} else {
+ val firstViewInShelfIndex = i + 1
val spaceBeforeShelf =
calculateGapAndDividerHeight(
- stack, previous = currentNotification, current = children[i + 1], i)
+ stack,
+ previous = currentNotification,
+ current = children[firstViewInShelfIndex],
+ currentIndex = firstViewInShelfIndex)
spaceBeforeShelf + shelfIntrinsicHeight
}
@@ -156,16 +160,17 @@
maxKeyguardNotifications =
infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
- dividerHeight = max(1, resources.getDimensionPixelSize(R.dimen.notification_divider_height))
+ dividerHeight =
+ max(1f, resources.getDimensionPixelSize(R.dimen.notification_divider_height).toFloat())
}
private val NotificationStackScrollLayout.childrenSequence: Sequence<ExpandableView>
get() = children.map { it as ExpandableView }
@VisibleForTesting
- fun onLockscreen() : Boolean {
- return statusBarStateController.state == KEYGUARD
- && lockscreenShadeTransitionController.fractionToShade == 0f
+ fun onLockscreen(): Boolean {
+ return statusBarStateController.state == KEYGUARD &&
+ lockscreenShadeTransitionController.fractionToShade == 0f
}
@VisibleForTesting
@@ -207,11 +212,12 @@
stack: NotificationStackScrollLayout,
previous: ExpandableView?,
current: ExpandableView?,
- visibleIndex: Int
+ currentIndex: Int
): Float {
- var height = stack.calculateGapHeight(previous, current, visibleIndex)
- height += dividerHeight
- return height
+ if (currentIndex == 0) {
+ return 0f
+ }
+ return stack.calculateGapHeight(previous, current, currentIndex) + dividerHeight
}
private fun NotificationStackScrollLayout.showableChildren() =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index c1869e0..e946bf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -558,6 +558,9 @@
if (!mUpdateMonitor.isDeviceInteractive()) {
if (!mKeyguardViewController.isShowing()
&& !mScreenOffAnimationController.isKeyguardShowDelayed()) {
+ if (mKeyguardStateController.isUnlocked()) {
+ return MODE_WAKE_AND_UNLOCK;
+ }
return MODE_ONLY_WAKE;
} else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
return MODE_WAKE_AND_UNLOCK_PULSING;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 8203987..367684f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -83,7 +83,6 @@
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
@@ -780,7 +779,8 @@
InteractionJankMonitor jankMonitor,
DeviceStateManager deviceStateManager,
DreamOverlayStateController dreamOverlayStateController,
- WiredChargingRippleController wiredChargingRippleController) {
+ WiredChargingRippleController wiredChargingRippleController,
+ IDreamManager dreamManager) {
super(context);
mNotificationsController = notificationsController;
mFragmentService = fragmentService;
@@ -871,6 +871,7 @@
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
mStartingSurfaceOptional = startingSurfaceOptional;
mNotifPipelineFlags = notifPipelineFlags;
+ mDreamManager = dreamManager;
lockscreenShadeTransitionController.setCentralSurfaces(this);
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
@@ -924,8 +925,6 @@
SysuiStatusBarStateController.RANK_STATUS_BAR);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- mDreamManager = IDreamManager.Stub.asInterface(
- ServiceManager.checkService(DreamService.DREAM_SERVICE));
mDisplay = mContext.getDisplay();
mDisplayId = mDisplay.getDisplayId();
@@ -1792,6 +1791,12 @@
collapseShade();
}
+ // We should exit the dream to prevent the activity from starting below the
+ // dream.
+ if (mKeyguardUpdateMonitor.isDreaming()) {
+ awakenDreams();
+ }
+
mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
.create(mContext)
@@ -2731,6 +2736,10 @@
mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
afterKeyguardGone);
} else {
+ // If the keyguard isn't showing but the device is dreaming, we should exit the dream.
+ if (mKeyguardUpdateMonitor.isDreaming()) {
+ awakenDreams();
+ }
action.onDismiss();
}
}
@@ -3964,7 +3973,7 @@
protected WindowManager mWindowManager;
protected IWindowManager mWindowManagerService;
- private IDreamManager mDreamManager;
+ private final IDreamManager mDreamManager;
protected Display mDisplay;
private int mDisplayId;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index 663490eb..ef68021 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -125,8 +125,7 @@
// Each row in separate section.
setGapHeight(gapHeight)
val spaceUsed =
- listOf(
- dividerHeight + rowHeight,
+ listOf(rowHeight,
dividerHeight + gapHeight + rowHeight,
dividerHeight + gapHeight + shelfHeight)
.sum()
@@ -149,9 +148,8 @@
val rowHeight = rowHeight
val shelfHeight = shelfHeight
val spaceUsed =
- listOf(
- dividerHeight + rowHeight,
- dividerHeight + shelfHeight)
+ listOf(rowHeight,
+ dividerHeight + shelfHeight)
.sum()
val availableSpace = spaceUsed + 1
val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
@@ -195,7 +193,7 @@
val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
previousView = null, stack = stackLayout, onLockscreen = true)
- assertThat(space).isEqualTo(5 + dividerHeight)
+ assertThat(space).isEqualTo(5)
}
@Test
@@ -209,7 +207,7 @@
val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
previousView = null, stack = stackLayout, onLockscreen = false)
- assertThat(space).isEqualTo(10 + dividerHeight)
+ assertThat(space).isEqualTo(10)
}
private fun computeMaxKeyguardNotifications(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index d6a2f0f..6864c65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -124,6 +124,7 @@
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
+ when(mKeyguardStateController.isUnlocked()).thenReturn(false);
when(mKeyguardBypassController.onBiometricAuthenticated(any(), anyBoolean()))
.thenReturn(true);
when(mAuthController.isUdfpsFingerDown()).thenReturn(false);
@@ -186,6 +187,24 @@
}
@Test
+ public void onBiometricAuthenticated_whenDeviceIsAlreadyUnlocked_wakeAndUnlock() {
+ reset(mUpdateMonitor);
+ reset(mStatusBarKeyguardViewManager);
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ when(mKeyguardStateController.isUnlocked()).thenReturn(true);
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
+ when(mDozeScrimController.isPulsing()).thenReturn(false);
+ // the value of isStrongBiometric doesn't matter here since we only care about the returned
+ // value of isUnlockingWithBiometricAllowed()
+ mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+ BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
+
+ verify(mKeyguardViewMediator).onWakeAndUnlocking();
+ assertThat(mBiometricUnlockController.getMode())
+ .isEqualTo(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
+ }
+
+ @Test
public void onBiometricAuthenticated_whenFingerprint_notifyKeyguardAuthenticated() {
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
// the value of isStrongBiometric doesn't matter here since we only care about the returned
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index d364505..16f934b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -477,7 +477,7 @@
mJankMonitor,
mDeviceStateManager,
mDreamOverlayStateController,
- mWiredChargingRippleController);
+ mWiredChargingRippleController, mDreamManager);
when(mKeyguardViewMediator.registerCentralSurfaces(
any(CentralSurfacesImpl.class),
any(NotificationPanelViewController.class),
@@ -534,6 +534,36 @@
}
@Test
+ public void executeRunnableDismissingKeyguard_dreaming_notShowing() throws RemoteException {
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(true);
+
+ mCentralSurfaces.executeRunnableDismissingKeyguard(() -> {},
+ /* cancelAction= */ null,
+ /* dismissShade= */ false,
+ /* afterKeyguardGone= */ false,
+ /* deferred= */ false);
+ mUiBgExecutor.runAllReady();
+ verify(mDreamManager, times(1)).awaken();
+ }
+
+ @Test
+ public void executeRunnableDismissingKeyguard_notDreaming_notShowing() throws RemoteException {
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(false);
+
+ mCentralSurfaces.executeRunnableDismissingKeyguard(() -> {},
+ /* cancelAction= */ null,
+ /* dismissShade= */ false,
+ /* afterKeyguardGone= */ false,
+ /* deferred= */ false);
+ mUiBgExecutor.runAllReady();
+ verify(mDreamManager, never()).awaken();
+ }
+
+ @Test
public void lockscreenStateMetrics_notShowing() {
// uninteresting state, except that fingerprint must be non-zero
when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index fc95cdd..15d3fa9 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -69,6 +69,7 @@
import android.util.TimeUtils;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillManager.AutofillCommitReason;
import android.view.autofill.AutofillManager.SmartSuggestionMode;
import android.view.autofill.AutofillManagerInternal;
import android.view.autofill.AutofillValue;
@@ -1657,11 +1658,12 @@
}
@Override
- public void finishSession(int sessionId, int userId) {
+ public void finishSession(int sessionId, int userId,
+ @AutofillCommitReason int commitReason) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
- service.finishSessionLocked(sessionId, getCallingUid());
+ service.finishSessionLocked(sessionId, getCallingUid(), commitReason);
} else if (sVerbose) {
Slog.v(TAG, "finishSession(): no service for " + userId);
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index aa5c501..fe85db2 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -70,6 +70,7 @@
import android.util.SparseArray;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillManager.AutofillCommitReason;
import android.view.autofill.AutofillManager.SmartSuggestionMode;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
@@ -423,7 +424,7 @@
}
@GuardedBy("mLock")
- void finishSessionLocked(int sessionId, int uid) {
+ void finishSessionLocked(int sessionId, int uid, @AutofillCommitReason int commitReason) {
if (!isEnabledLocked()) {
return;
}
@@ -438,7 +439,7 @@
final Session.SaveResult saveResult = session.showSaveLocked();
- session.logContextCommitted(saveResult.getNoSaveUiReason());
+ session.logContextCommitted(saveResult.getNoSaveUiReason(), commitReason);
if (saveResult.isLogSaveShown()) {
session.logSaveUiShown();
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
new file mode 100644
index 0000000..c6e595b
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2022 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.server.autofill;
+
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
+import static android.service.autofill.FillEventHistory.Event.UiType;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_ACTIVITY_FINISHED;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_CHANGED;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_CLICKED;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_COMMITTED;
+
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__ANY_SHOWN;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_ACTIVITY_FINISHED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_REQUEST_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUS_CHANGED;
+import static com.android.server.autofill.Helper.sVerbose;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.service.autofill.Dataset;
+import android.util.Slog;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Optional;
+
+/** Helper class to track and log Autofill presentation stats. */
+public final class PresentationStatsEventLogger {
+ private static final String TAG = "PresentationStatsEventLogger";
+
+ /**
+ * Reasons why presentation was not shown. These are wrappers around
+ * {@link com.android.os.AtomsProto.AutofillPresentationEventReported.PresentationEventResult}.
+ */
+ @IntDef(prefix = { "NOT_SHOWN_REASON" }, value = {
+ NOT_SHOWN_REASON_ANY_SHOWN,
+ NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED,
+ NOT_SHOWN_REASON_VIEW_CHANGED,
+ NOT_SHOWN_REASON_ACTIVITY_FINISHED,
+ NOT_SHOWN_REASON_REQUEST_TIMEOUT,
+ NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY,
+ NOT_SHOWN_REASON_UNKNOWN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NotShownReason {}
+ public static final int NOT_SHOWN_REASON_ANY_SHOWN = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__ANY_SHOWN;
+ public static final int NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUS_CHANGED;
+ public static final int NOT_SHOWN_REASON_VIEW_CHANGED = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
+ public static final int NOT_SHOWN_REASON_ACTIVITY_FINISHED = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_ACTIVITY_FINISHED;
+ public static final int NOT_SHOWN_REASON_REQUEST_TIMEOUT = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_REQUEST_TIMEOUT;
+ public static final int NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
+ public static final int NOT_SHOWN_REASON_UNKNOWN = AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
+
+ private final int mSessionId;
+ private Optional<PresentationStatsEventInternal> mEventInternal;
+
+ private PresentationStatsEventLogger(int sessionId) {
+ mSessionId = sessionId;
+ mEventInternal = Optional.empty();
+ }
+
+ public static PresentationStatsEventLogger forSessionId(int sessionId) {
+ return new PresentationStatsEventLogger(sessionId);
+ }
+
+ public void startNewEvent() {
+ if (mEventInternal.isPresent()) {
+ Slog.e(TAG, "Failed to start new event because already have active event.");
+ return;
+ }
+ mEventInternal = Optional.of(new PresentationStatsEventInternal());
+ }
+
+ public void maybeSetRequestId(int requestId) {
+ mEventInternal.ifPresent(event -> event.mRequestId = requestId);
+ }
+
+ public void maybeSetNoPresentationEventReason(@NotShownReason int reason) {
+ mEventInternal.ifPresent(event -> {
+ if (event.mCountShown == 0) {
+ event.mNoPresentationReason = reason;
+ }
+ });
+ }
+
+ public void maybeSetAvailableCount(@Nullable List<Dataset> datasetList,
+ AutofillId currentViewId) {
+ mEventInternal.ifPresent(event -> {
+ int availableCount = getDatasetCountForAutofillId(datasetList, currentViewId);
+ event.mAvailableCount = availableCount;
+ event.mIsDatasetAvailable = availableCount > 0;
+ });
+ }
+
+ public void maybeSetCountShown(@Nullable List<Dataset> datasetList,
+ AutofillId currentViewId) {
+ mEventInternal.ifPresent(event -> {
+ int countShown = getDatasetCountForAutofillId(datasetList, currentViewId);
+ event.mCountShown = countShown;
+ if (countShown > 0) {
+ event.mNoPresentationReason = NOT_SHOWN_REASON_ANY_SHOWN;
+ }
+ });
+ }
+
+ private static int getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
+ AutofillId currentViewId) {
+ int availableCount = 0;
+ if (datasetList != null) {
+ for (int i = 0; i < datasetList.size(); i++) {
+ Dataset data = datasetList.get(i);
+ if (data != null && data.getFieldIds() != null
+ && data.getFieldIds().contains(currentViewId)) {
+ availableCount += 1;
+ }
+ }
+ }
+ return availableCount;
+ }
+
+ public void maybeSetCountFilteredUserTyping(int countFilteredUserTyping) {
+ mEventInternal.ifPresent(event -> {
+ event.mCountFilteredUserTyping = countFilteredUserTyping;
+ });
+ }
+
+ public void maybeSetCountNotShownImePresentationNotDrawn(
+ int countNotShownImePresentationNotDrawn) {
+ mEventInternal.ifPresent(event -> {
+ event.mCountNotShownImePresentationNotDrawn = countNotShownImePresentationNotDrawn;
+ });
+ }
+
+ public void maybeSetCountNotShownImeUserNotSeen(int countNotShownImeUserNotSeen) {
+ mEventInternal.ifPresent(event -> {
+ event.mCountNotShownImeUserNotSeen = countNotShownImeUserNotSeen;
+ });
+ }
+
+ public void maybeSetDisplayPresentationType(@UiType int uiType) {
+ mEventInternal.ifPresent(event -> {
+ event.mDisplayPresentationType = getDisplayPresentationType(uiType);
+ });
+ }
+
+ public void logAndEndEvent() {
+ if (!mEventInternal.isPresent()) {
+ Slog.wtf(null, "Shouldn't be logging AutofillPresentationEventReported again for same "
+ + "event");
+ return;
+ }
+ PresentationStatsEventInternal event = mEventInternal.get();
+ if (sVerbose) {
+ Slog.v(TAG, "Log AutofillPresentationEventReported:"
+ + " requestId=" + event.mRequestId
+ + " sessionId=" + mSessionId
+ + " mNoPresentationEventReason=" + event.mNoPresentationReason
+ + " mAvailableCount=" + event.mAvailableCount
+ + " mCountShown=" + event.mCountShown
+ + " mCountFilteredUserTyping=" + event.mCountFilteredUserTyping
+ + " mCountNotShownImePresentationNotDrawn="
+ + event.mCountNotShownImePresentationNotDrawn
+ + " mCountNotShownImeUserNotSeen=" + event.mCountNotShownImeUserNotSeen
+ + " mDisplayPresentationType=" + event.mDisplayPresentationType);
+ }
+
+ // TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
+ if (!event.mIsDatasetAvailable) {
+ mEventInternal = Optional.empty();
+ return;
+ }
+ FrameworkStatsLog.write(
+ AUTOFILL_PRESENTATION_EVENT_REPORTED,
+ event.mRequestId,
+ mSessionId,
+ event.mNoPresentationReason,
+ event.mAvailableCount,
+ event.mCountShown,
+ event.mCountFilteredUserTyping,
+ event.mCountNotShownImePresentationNotDrawn,
+ event.mCountNotShownImeUserNotSeen,
+ event.mDisplayPresentationType);
+ mEventInternal = Optional.empty();
+ }
+
+ private final class PresentationStatsEventInternal {
+ int mRequestId;
+ @NotShownReason int mNoPresentationReason = NOT_SHOWN_REASON_UNKNOWN;
+ boolean mIsDatasetAvailable;
+ int mAvailableCount;
+ int mCountShown;
+ int mCountFilteredUserTyping;
+ int mCountNotShownImePresentationNotDrawn;
+ int mCountNotShownImeUserNotSeen;
+ int mDisplayPresentationType = AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
+
+ PresentationStatsEventInternal() {}
+ }
+
+ static int getNoPresentationEventReason(
+ @AutofillManager.AutofillCommitReason int commitReason) {
+ switch (commitReason) {
+ case COMMIT_REASON_VIEW_COMMITTED:
+ return NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY;
+ case COMMIT_REASON_ACTIVITY_FINISHED:
+ return NOT_SHOWN_REASON_ACTIVITY_FINISHED;
+ case COMMIT_REASON_VIEW_CHANGED:
+ return NOT_SHOWN_REASON_VIEW_CHANGED;
+ case COMMIT_REASON_VIEW_CLICKED:
+ // TODO(b/234185326): Add separate reason for view clicked.
+ default:
+ return NOT_SHOWN_REASON_UNKNOWN;
+ }
+ }
+
+ private static int getDisplayPresentationType(@UiType int uiType) {
+ switch (uiType) {
+ case UI_TYPE_MENU:
+ return AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU;
+ case UI_TYPE_INLINE:
+ return AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
+ case UI_TYPE_DIALOG:
+ return AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG;
+ default:
+ return AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
+ }
+ }
+}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ca0a780..0fe9f8f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -32,6 +32,7 @@
import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_UNKNOWN;
import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
@@ -42,6 +43,9 @@
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
import static com.android.server.autofill.Helper.toArray;
+import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_REQUEST_TIMEOUT;
+import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_VIEW_CHANGED;
+import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
@@ -107,6 +111,7 @@
import android.view.KeyEvent;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillManager.AutofillCommitReason;
import android.view.autofill.AutofillManager.SmartSuggestionMode;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
@@ -391,6 +396,10 @@
}
};
+ @NonNull
+ @GuardedBy("mLock")
+ private PresentationStatsEventLogger mPresentationStatsEventLogger;
+
void onSwitchInputMethodLocked() {
// One caveat is that for the case where the focus is on a field for which regular autofill
// returns null, and augmented autofill is triggered, and then the user switches the input
@@ -924,6 +933,7 @@
Slog.v(TAG, "Requesting structure for request #" + ordinal + " ,requestId=" + requestId
+ ", flags=" + flags);
}
+ mPresentationStatsEventLogger.maybeSetRequestId(requestId);
// If the focus changes very quickly before the first request is returned each focus change
// triggers a new partition and we end up with many duplicate partitions. This is
@@ -1021,6 +1031,7 @@
mComponentName = componentName;
mCompatMode = compatMode;
mSessionState = STATE_ACTIVE;
+ mPresentationStatsEventLogger = PresentationStatsEventLogger.forSessionId(sessionId);
synchronized (mLock) {
mSessionFlags = new SessionFlags();
mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly;
@@ -1271,6 +1282,11 @@
message.length());
}
}
+
+ // TODO(b/234185326): Add separate reason for failures.
+ mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+ NOT_SHOWN_REASON_REQUEST_TIMEOUT);
+ mPresentationStatsEventLogger.logAndEndEvent();
}
notifyUnavailableToClient(AutofillManager.STATE_UNKNOWN_FAILED,
/* autofillableIds= */ null);
@@ -1859,7 +1875,8 @@
*/
public void logContextCommitted() {
mHandler.sendMessage(obtainMessage(Session::handleLogContextCommitted, this,
- Event.NO_SAVE_UI_REASON_NONE));
+ Event.NO_SAVE_UI_REASON_NONE,
+ COMMIT_REASON_UNKNOWN));
}
/**
@@ -1867,13 +1884,16 @@
* when necessary.
*
* @param saveDialogNotShowReason The reason why a save dialog was not shown.
+ * @param commitReason The reason why context is committed.
*/
- public void logContextCommitted(@NoSaveReason int saveDialogNotShowReason) {
+ public void logContextCommitted(@NoSaveReason int saveDialogNotShowReason,
+ @AutofillCommitReason int commitReason) {
mHandler.sendMessage(obtainMessage(Session::handleLogContextCommitted, this,
- saveDialogNotShowReason));
+ saveDialogNotShowReason, commitReason));
}
- private void handleLogContextCommitted(@NoSaveReason int saveDialogNotShowReason) {
+ private void handleLogContextCommitted(@NoSaveReason int saveDialogNotShowReason,
+ @AutofillCommitReason int commitReason) {
final FillResponse lastResponse;
synchronized (mLock) {
lastResponse = getLastResponseLocked("logContextCommited(%s)");
@@ -1903,28 +1923,35 @@
// Sets field classification scores
if (userData != null && fcStrategy != null) {
- logFieldClassificationScore(fcStrategy, userData, saveDialogNotShowReason);
+ logFieldClassificationScore(fcStrategy, userData, saveDialogNotShowReason,
+ commitReason);
} else {
- logContextCommitted(null, null, saveDialogNotShowReason);
+ logContextCommitted(null, null, saveDialogNotShowReason, commitReason);
}
}
private void logContextCommitted(@Nullable ArrayList<AutofillId> detectedFieldIds,
@Nullable ArrayList<FieldClassification> detectedFieldClassifications,
- @NoSaveReason int saveDialogNotShowReason) {
+ @NoSaveReason int saveDialogNotShowReason,
+ @AutofillCommitReason int commitReason) {
synchronized (mLock) {
logContextCommittedLocked(detectedFieldIds, detectedFieldClassifications,
- saveDialogNotShowReason);
+ saveDialogNotShowReason, commitReason);
}
}
@GuardedBy("mLock")
private void logContextCommittedLocked(@Nullable ArrayList<AutofillId> detectedFieldIds,
@Nullable ArrayList<FieldClassification> detectedFieldClassifications,
- @NoSaveReason int saveDialogNotShowReason) {
+ @NoSaveReason int saveDialogNotShowReason,
+ @AutofillCommitReason int commitReason) {
final FillResponse lastResponse = getLastResponseLocked("logContextCommited(%s)");
if (lastResponse == null) return;
+ mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+ PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
+ mPresentationStatsEventLogger.logAndEndEvent();
+
final int flags = lastResponse.getFlags();
if ((flags & FillResponse.FLAG_TRACK_CONTEXT_COMMITED) == 0) {
if (sVerbose) Slog.v(TAG, "logContextCommittedLocked(): ignored by flags " + flags);
@@ -2102,7 +2129,8 @@
*/
private void logFieldClassificationScore(@NonNull FieldClassificationStrategy fcStrategy,
@NonNull FieldClassificationUserData userData,
- @NoSaveReason int saveDialogNotShowReason) {
+ @NoSaveReason int saveDialogNotShowReason,
+ @AutofillCommitReason int commitReason) {
final String[] userValues = userData.getValues();
final String[] categoryIds = userData.getCategoryIds();
@@ -2148,7 +2176,7 @@
final RemoteCallback callback = new RemoteCallback((result) -> {
if (result == null) {
if (sDebug) Slog.d(TAG, "setFieldClassificationScore(): no results");
- logContextCommitted(null, null, saveDialogNotShowReason);
+ logContextCommitted(null, null, saveDialogNotShowReason, commitReason);
return;
}
final Scores scores = result.getParcelable(EXTRA_SCORES);
@@ -2210,7 +2238,7 @@
}
logContextCommitted(detectedFieldIds, detectedFieldClassifications,
- saveDialogNotShowReason);
+ saveDialogNotShowReason, commitReason);
});
fcStrategy.calculateScores(callback, currentValues, userValues, categoryIds,
@@ -2891,6 +2919,9 @@
if (sDebug) {
Slog.d(TAG, "Set the response has expired.");
}
+ mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+ NOT_SHOWN_REASON_VIEW_CHANGED);
+ mPresentationStatsEventLogger.logAndEndEvent();
return;
}
@@ -2936,6 +2967,7 @@
if (!isRequestSupportFillDialog(flags)) {
mSessionFlags.mFillDialogDisabled = true;
}
+ mPresentationStatsEventLogger.startNewEvent();
requestNewFillResponseLocked(viewState, ViewState.STATE_STARTED_SESSION, flags);
break;
case ACTION_VALUE_CHANGED:
@@ -2994,6 +3026,10 @@
return;
}
+ mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+ NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
+ mPresentationStatsEventLogger.logAndEndEvent();
+
if ((flags & FLAG_MANUAL_REQUEST) == 0) {
// Not a manual request
if (mAugmentedAutofillableIds != null && mAugmentedAutofillableIds.contains(
@@ -3020,10 +3056,18 @@
}
}
+ mPresentationStatsEventLogger.startNewEvent();
if (requestNewFillResponseOnViewEnteredIfNecessaryLocked(id, viewState, flags)) {
return;
}
+ if (viewState.getResponse() != null) {
+ FillResponse response = viewState.getResponse();
+ mPresentationStatsEventLogger.maybeSetRequestId(response.getRequestId());
+ mPresentationStatsEventLogger.maybeSetAvailableCount(
+ response.getDatasets(), mCurrentViewId);
+ }
+
if (isSameViewEntered) {
setFillDialogDisabledAndStartInput();
return;
@@ -3042,6 +3086,10 @@
// on the IME side if it arrives before the input view is finished on the IME.
mInlineSessionController.resetInlineFillUiLocked();
mCurrentViewId = null;
+
+ mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+ NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
+ mPresentationStatsEventLogger.logAndEndEvent();
}
break;
default:
@@ -3215,6 +3263,10 @@
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
mService.logDatasetShown(id, mClientState, UI_TYPE_DIALOG);
+
+ mPresentationStatsEventLogger.maybeSetCountShown(
+ response.getDatasets(), mCurrentViewId);
+ mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_DIALOG);
}
// Just show fill dialog once, so disabled after shown.
// Note: Cannot disable before requestShowFillDialog() because the method
@@ -3232,9 +3284,15 @@
if (requestShowInlineSuggestionsLocked(response, filterText)) {
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_INLINE_SHOWN);
- //TODO(b/137800469): Fix it to log showed only when IME asks for inflation,
+ // TODO(b/137800469): Fix it to log showed only when IME asks for inflation,
// rather than here where framework sends back the response.
mService.logDatasetShown(id, mClientState, UI_TYPE_INLINE);
+
+ // TODO(b/234475358): Log more accurate value of number of inline suggestions
+ // shown, inflated, and filtered.
+ mPresentationStatsEventLogger.maybeSetCountShown(
+ response.getDatasets(), mCurrentViewId);
+ mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_INLINE);
return;
}
}
@@ -3246,6 +3304,10 @@
synchronized (mLock) {
mService.logDatasetShown(id, mClientState, UI_TYPE_MENU);
+
+ mPresentationStatsEventLogger.maybeSetCountShown(
+ response.getDatasets(), mCurrentViewId);
+ mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_MENU);
}
synchronized (mLock) {
@@ -3794,6 +3856,9 @@
mResponses.put(requestId, newResponse);
mClientState = newClientState != null ? newClientState : newResponse.getClientState();
+ mPresentationStatsEventLogger.maybeSetAvailableCount(
+ newResponse.getDatasets(), mCurrentViewId);
+
setViewStatesLocked(newResponse, ViewState.STATE_FILLABLE, false);
updateFillDialogTriggerIdsLocked();
updateTrackedIdsLocked();
diff --git a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
index bd2a97d..229799a 100644
--- a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
+++ b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
@@ -29,6 +29,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.CollectionUtils;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -267,6 +268,21 @@
}
}
+ /**
+ * Dumps current companion device association states.
+ */
+ public void dump(@NonNull PrintWriter out) {
+ out.append("Companion Device Associations: ");
+ if (getAssociations().isEmpty()) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ for (AssociationInfo a : getAssociations()) {
+ out.append(" ").append(a.toString()).append('\n');
+ }
+ }
+ }
+
private void broadcastChange(@ChangeType int changeType, AssociationInfo association) {
synchronized (mListeners) {
for (OnChangeListener listener : mListeners) {
diff --git a/services/companion/java/com/android/server/companion/CompanionApplicationController.java b/services/companion/java/com/android/server/companion/CompanionApplicationController.java
index 6eb8e26..64729a2 100644
--- a/services/companion/java/com/android/server/companion/CompanionApplicationController.java
+++ b/services/companion/java/com/android/server/companion/CompanionApplicationController.java
@@ -33,6 +33,7 @@
import com.android.internal.infra.PerUser;
import com.android.internal.util.CollectionUtils;
+import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -234,6 +235,28 @@
primaryServiceConnector.postOnDeviceDisappeared(association);
}
+ void dump(@NonNull PrintWriter out) {
+ out.append("Companion Device Application Controller: \n");
+
+ synchronized (mBoundCompanionApplications) {
+ out.append(" Bound Companion Applications: ");
+ if (mBoundCompanionApplications.size() == 0) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ mBoundCompanionApplications.dump(out);
+ }
+ }
+
+ out.append(" Companion Applications Scheduled For Rebinding: ");
+ if (mScheduledForRebindingCompanionApplications.size() == 0) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ mScheduledForRebindingCompanionApplications.dump(out);
+ }
+ }
+
private void onPrimaryServiceBindingDied(@UserIdInt int userId, @NonNull String packageName) {
if (DEBUG) Log.i(TAG, "onPrimaryServiceBindingDied() u" + userId + "/" + packageName);
@@ -333,5 +356,23 @@
}
}
}
+
+ private void dump(@NonNull PrintWriter out) {
+ for (int i = 0; i < size(); i++) {
+ final int userId = keyAt(i);
+ final Map<String, T> forUser = get(userId);
+ if (forUser.isEmpty()) {
+ out.append(" u").append(String.valueOf(userId)).append(": <empty>\n");
+ }
+
+ for (Map.Entry<String, T> packageValue : forUser.entrySet()) {
+ final String packageName = packageValue.getKey();
+ final T value = packageValue.getValue();
+ out.append(" u").append(String.valueOf(userId)).append("\\")
+ .append(packageName).append(" -> ")
+ .append(value.toString()).append('\n');
+ }
+ }
+ }
}
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 0bfe282..3f7cba6 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -764,14 +764,9 @@
return;
}
- // TODO(b/218615185): mAssociationStore.dump() instead
- out.append("Companion Device Associations:").append('\n');
- for (AssociationInfo a : mAssociationStore.getAssociations()) {
- out.append(" ").append(a.toString()).append('\n');
- }
-
- // TODO(b/218615185): mDevicePresenceMonitor.dump()
- // TODO(b/218615185): mCompanionAppController.dump()
+ mAssociationStore.dump(out);
+ mDevicePresenceMonitor.dump(out);
+ mCompanionAppController.dump(out);
}
}
diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
index 89ed301e..0e4870a 100644
--- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
+++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
@@ -33,6 +33,7 @@
import com.android.server.companion.AssociationStore;
+import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
@@ -293,6 +294,54 @@
throw new SecurityException("Caller is neither Shell nor Root");
}
+ /**
+ * Dumps system information about devices that are marked as "present".
+ */
+ public void dump(@NonNull PrintWriter out) {
+ out.append("Companion Device Present: ");
+ if (mConnectedBtDevices.isEmpty()
+ && mNearbyBleDevices.isEmpty()
+ && mReportedSelfManagedDevices.isEmpty()) {
+ out.append("<empty>\n");
+ return;
+ } else {
+ out.append("\n");
+ }
+
+ out.append(" Connected Bluetooth Devices: ");
+ if (mConnectedBtDevices.isEmpty()) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ for (int associationId : mConnectedBtDevices) {
+ AssociationInfo a = mAssociationStore.getAssociationById(associationId);
+ out.append(" ").append(a.toShortString()).append('\n');
+ }
+ }
+
+ out.append(" Nearby BLE Devices: ");
+ if (mNearbyBleDevices.isEmpty()) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ for (int associationId : mNearbyBleDevices) {
+ AssociationInfo a = mAssociationStore.getAssociationById(associationId);
+ out.append(" ").append(a.toShortString()).append('\n');
+ }
+ }
+
+ out.append(" Self-Reported Devices: ");
+ if (mReportedSelfManagedDevices.isEmpty()) {
+ out.append("<empty>\n");
+ } else {
+ out.append("\n");
+ for (int associationId : mReportedSelfManagedDevices) {
+ AssociationInfo a = mAssociationStore.getAssociationById(associationId);
+ out.append(" ").append(a.toShortString()).append('\n');
+ }
+ }
+ }
+
private class SimulatedDevicePresenceSchedulerHelper extends Handler {
SimulatedDevicePresenceSchedulerHelper() {
super(Looper.getMainLooper());
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 38d0e30..5026f31 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4177,7 +4177,8 @@
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
- HostingRecord hostingRecord = new HostingRecord("service", r.instanceName,
+ HostingRecord hostingRecord = new HostingRecord(
+ HostingRecord.HOSTING_TYPE_SERVICE, r.instanceName,
r.definingPackageName, r.definingUid, r.serviceInfo.processName);
ProcessRecord app;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a2106f9..71682f2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -128,6 +128,10 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
import static com.android.server.am.ProcessList.ProcStartHandler;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BACKUP;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_INSTRUMENTATION;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PERSISTENT;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_SYSTEM;
import static com.android.server.net.NetworkPolicyManagerInternal.updateBlockedReasonsWithProcState;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
@@ -1549,7 +1553,8 @@
@GuardedBy("mProcLock")
private ParcelFileDescriptor[] mLifeMonitorFds;
- static final HostingRecord sNullHostingRecord = new HostingRecord(null);
+ static final HostingRecord sNullHostingRecord =
+ new HostingRecord(HostingRecord.HOSTING_TYPE_EMPTY);
/**
* Used to notify activity lifecycle events.
*/
@@ -1872,11 +1877,12 @@
false,
0,
null,
- new HostingRecord("system"));
+ new HostingRecord(HostingRecord.HOSTING_TYPE_SYSTEM));
app.setPersistent(true);
app.setPid(MY_PID);
app.mState.setMaxAdj(ProcessList.SYSTEM_ADJ);
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
+ app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_SYSTEM);
addPidLocked(app);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -4179,7 +4185,9 @@
mi.getTotalRss(),
ProcessStats.ADD_PSS_EXTERNAL_SLOW,
duration,
- holder.appVersion);
+ holder.appVersion,
+ profile.getCurrentHostingComponentTypes(),
+ profile.getHistoricalHostingComponentTypes());
});
}
}
@@ -4237,7 +4245,9 @@
tmpUss[2],
ProcessStats.ADD_PSS_EXTERNAL,
duration,
- holder.appVersion);
+ holder.appVersion,
+ profile.getCurrentHostingComponentTypes(),
+ profile.getHistoricalHostingComponentTypes());
});
}
}
@@ -4722,7 +4732,7 @@
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
- new HostingRecord("link fail", processName),
+ new HostingRecord(HostingRecord.HOSTING_TYPE_LINK_FAIL, processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return false;
}
@@ -4991,6 +5001,17 @@
checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
}
+
+ final HostingRecord hostingRecord = app.getHostingRecord();
+ final String action = hostingRecord.getAction();
+ String shortAction = action;
+ if (action != null) {
+ // only log the last part of the action string to save stats data.
+ int index = action.lastIndexOf(".");
+ if (index != -1 && index != action.length() - 1) {
+ shortAction = action.substring(index + 1);
+ }
+ }
FrameworkStatsLog.write(
FrameworkStatsLog.PROCESS_START_TIME,
app.info.uid,
@@ -5000,8 +5021,10 @@
app.getStartElapsedTime(),
(int) (bindApplicationTimeMillis - app.getStartUptime()),
(int) (SystemClock.uptimeMillis() - app.getStartUptime()),
- app.getHostingRecord().getType(),
- (app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : ""));
+ hostingRecord.getType(),
+ hostingRecord.getName(),
+ shortAction,
+ HostingRecord.getHostingTypeIdStatsd(hostingRecord.getType()));
return true;
}
@@ -5100,7 +5123,7 @@
Slog.v(TAG_PROCESSES, "Starting process on hold: " + procs.get(ip));
}
mProcessList.startProcessLocked(procs.get(ip),
- new HostingRecord("on-hold"),
+ new HostingRecord(HostingRecord.HOSTING_TYPE_ON_HOLD),
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
}
}
@@ -6416,8 +6439,13 @@
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
if (!"android".equals(app.packageName)) {
- addAppLocked(app, null, false, null /* ABI override */,
+ final ProcessRecord proc = addAppLocked(
+ app, null, false, null /* ABI override */,
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
+ if (proc != null) {
+ proc.mProfile.addHostingComponentType(
+ HOSTING_COMPONENT_TYPE_PERSISTENT);
+ }
}
}
} catch (RemoteException ex) {
@@ -6686,7 +6714,7 @@
isSdkSandbox,
sdkSandboxUid,
sdkSandboxClientAppPackage,
- new HostingRecord("added application",
+ new HostingRecord(HostingRecord.HOSTING_TYPE_ADDED_APPLICATION,
customProcess != null ? customProcess : info.processName));
updateLruProcessLocked(app, false, null);
updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
@@ -6715,7 +6743,8 @@
}
if (app.getThread() == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
- mProcessList.startProcessLocked(app, new HostingRecord("added application",
+ mProcessList.startProcessLocked(app, new HostingRecord(
+ HostingRecord.HOSTING_TYPE_ADDED_APPLICATION,
customProcess != null ? customProcess : app.processName),
zygotePolicyFlags, disableHiddenApiChecks, disableTestApiChecks,
abiOverride);
@@ -11295,7 +11324,9 @@
holder.state.getPackage(),
myTotalPss, myTotalUss, myTotalRss, reportType,
endTime-startTime,
- holder.appVersion);
+ holder.appVersion,
+ r.mProfile.getCurrentHostingComponentTypes(),
+ r.mProfile.getHistoricalHostingComponentTypes());
});
}
}
@@ -11938,7 +11969,9 @@
holder.state.getName(),
holder.state.getPackage(),
myTotalPss, myTotalUss, myTotalRss, reportType, endTime-startTime,
- holder.appVersion);
+ holder.appVersion,
+ r.mProfile.getCurrentHostingComponentTypes(),
+ r.mProfile.getHistoricalHostingComponentTypes());
});
}
}
@@ -12366,7 +12399,8 @@
mProcessList.addProcessNameLocked(app);
app.setPendingStart(false);
- mProcessList.startProcessLocked(app, new HostingRecord("restart", app.processName),
+ mProcessList.startProcessLocked(app, new HostingRecord(
+ HostingRecord.HOSTING_TYPE_RESTART, app.processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return true;
} else if (pid > 0 && pid != MY_PID) {
@@ -12751,7 +12785,7 @@
// startProcessLocked() returns existing proc's record if it's already running
ProcessRecord proc = startProcessLocked(app.processName, app,
false, 0,
- new HostingRecord("backup", hostingName),
+ new HostingRecord(HostingRecord.HOSTING_TYPE_BACKUP, hostingName),
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS, false, false);
if (proc == null) {
Slog.e(TAG, "Unable to start backup agent process " + r);
@@ -12772,6 +12806,8 @@
newBackupUid = proc.isInFullBackup() ? r.appInfo.uid : -1;
mBackupTargets.put(targetUserId, r);
+ proc.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BACKUP);
+
// Try not to kill the process during backup
updateOomAdjLocked(proc, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -12814,7 +12850,15 @@
}
synchronized (this) {
- mBackupTargets.delete(userId);
+ final int indexOfKey = mBackupTargets.indexOfKey(userId);
+ if (indexOfKey >= 0) {
+ final BackupRecord backupTarget = mBackupTargets.valueAt(indexOfKey);
+ if (backupTarget != null && backupTarget.app != null) {
+ backupTarget.app.mProfile.clearHostingComponentType(
+ HOSTING_COMPONENT_TYPE_BACKUP);
+ }
+ mBackupTargets.removeAt(indexOfKey);
+ }
}
JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
@@ -12892,6 +12936,7 @@
final ProcessRecord proc = backupTarget.app;
updateOomAdjLocked(proc, OomAdjuster.OOM_ADJ_REASON_NONE);
proc.setInFullBackup(false);
+ proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BACKUP);
oldBackupUid = backupTarget != null ? backupTarget.appInfo.uid : -1;
@@ -14620,6 +14665,7 @@
}
app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
disableTestApiChecks, abiOverride, ZYGOTE_POLICY_FLAG_EMPTY);
+ app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
}
app.setActiveInstrumentation(activeInstr);
@@ -14744,6 +14790,7 @@
if (!mActiveInstrumentation.contains(activeInstr)) {
mActiveInstrumentation.add(activeInstr);
}
+ app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -14873,6 +14920,7 @@
instr.removeProcess(app);
app.setActiveInstrumentation(null);
}
+ app.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
if (app.isSdkSandbox) {
// For sharedUid apps this will kill all sdk sandbox processes, which is not ideal.
@@ -15753,6 +15801,7 @@
if (app.isPersistent()) {
addAppLocked(app.info, null, false, null /* ABI override */,
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
+ app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PERSISTENT);
}
}
}
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 16a7283..61d8568 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -573,7 +573,9 @@
holder.state.getPackage(),
pss, uss, rss,
statType, pssDuration,
- holder.appVersion);
+ holder.appVersion,
+ profile.getCurrentHostingComponentTypes(),
+ profile.getHistoricalHostingComponentTypes());
});
if (DEBUG_PSS) {
Slog.d(TAG_PSS,
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index d2e40c5..f7aa7c15 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1870,8 +1870,9 @@
r.curApp = mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
- new HostingRecord("broadcast", r.curComponent), isActivityCapable
- ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
+ new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST, r.curComponent,
+ r.intent.getAction()),
+ isActivityCapable ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
(r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
if (r.curApp == null) {
// Ah, this recipient is unavailable. Finish it if necessary,
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index 24e815e..728792f 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -24,6 +24,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
import static com.android.server.am.ActivityManagerService.TAG_MU;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PROVIDER;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -482,7 +483,7 @@
checkTime(startTime, "getContentProviderImpl: before start process");
proc = mService.startProcessLocked(
cpi.processName, cpr.appInfo, false, 0,
- new HostingRecord("content provider",
+ new HostingRecord(HostingRecord.HOSTING_TYPE_CONTENT_PROVIDER,
new ComponentName(
cpi.applicationInfo.packageName, cpi.name)),
Process.ZYGOTE_POLICY_FLAG_EMPTY, false, false);
@@ -701,6 +702,9 @@
dst.onProviderPublishStatusLocked(true);
}
dst.mRestartCount = 0;
+ if (hasProviderConnectionLocked(r)) {
+ r.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
+ }
}
// update the app's oom adj value and each provider's usage stats
@@ -1375,6 +1379,9 @@
conn.startAssociationIfNeeded();
conn.initializeCount(stable);
cpr.connections.add(conn);
+ if (cpr.proc != null) {
+ cpr.proc.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
+ }
pr.addProviderConnection(conn);
mService.startAssociationLocked(r.uid, r.processName, r.mState.getCurProcState(),
cpr.uid, cpr.appInfo.longVersionCode, cpr.name, cpr.info.processName);
@@ -1418,6 +1425,16 @@
return true;
}
+ @GuardedBy("mService")
+ private boolean hasProviderConnectionLocked(ProcessRecord proc) {
+ for (int i = proc.mProviders.numberOfProviders() - 1; i >= 0; i--) {
+ if (!proc.mProviders.getProviderAt(i).connections.isEmpty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void handleProviderRemoval(ContentProviderConnection conn, boolean stable,
boolean updateOomAdj) {
synchronized (mService) {
@@ -1429,6 +1446,9 @@
final ContentProviderRecord cpr = conn.provider;
conn.stopAssociation();
cpr.connections.remove(conn);
+ if (cpr.proc != null && !hasProviderConnectionLocked(cpr.proc)) {
+ cpr.proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
+ }
conn.client.mProviders.removeProviderConnection(conn);
if (conn.client.mState.getSetProcState()
< ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
@@ -1737,6 +1757,9 @@
// In the protocol here, we don't expect the client to correctly
// clean up this connection, we'll just remove it.
cpr.connections.remove(i);
+ if (cpr.proc != null && !hasProviderConnectionLocked(cpr.proc)) {
+ cpr.proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
+ }
if (conn.client.mProviders.removeProviderConnection(conn)) {
mService.stopAssociationLocked(capp.uid, capp.processName,
cpr.uid, cpr.appInfo.longVersionCode, cpr.name, cpr.info.processName);
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index bbf5861..f88a8ce 100644
--- a/services/core/java/com/android/server/am/HostingRecord.java
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -16,7 +16,10 @@
package com.android.server.am;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
+import android.os.ProcessStartTime;
/**
* This class describes various information required to start a process.
@@ -43,6 +46,9 @@
*
* {@code mIsTopApp} will be passed to {@link android.os.Process#start}. So Zygote will initialize
* the process with high priority.
+ *
+ * {@code mAction} the broadcast's intent action if the process is started for a broadcast
+ * receiver.
*/
public final class HostingRecord {
@@ -50,51 +56,77 @@
private static final int WEBVIEW_ZYGOTE = 1;
private static final int APP_ZYGOTE = 2;
- private final String mHostingType;
+ public static final String HOSTING_TYPE_ACTIVITY = "activity";
+ public static final String HOSTING_TYPE_ADDED_APPLICATION = "added application";
+ public static final String HOSTING_TYPE_BACKUP = "backup";
+ public static final String HOSTING_TYPE_BROADCAST = "broadcast";
+ public static final String HOSTING_TYPE_CONTENT_PROVIDER = "content provider";
+ public static final String HOSTING_TYPE_LINK_FAIL = "link fail";
+ public static final String HOSTING_TYPE_ON_HOLD = "on-hold";
+ public static final String HOSTING_TYPE_NEXT_ACTIVITY = "next-activity";
+ public static final String HOSTING_TYPE_NEXT_TOP_ACTIVITY = "next-top-activity";
+ public static final String HOSTING_TYPE_RESTART = "restart";
+ public static final String HOSTING_TYPE_SERVICE = "service";
+ public static final String HOSTING_TYPE_SYSTEM = "system";
+ public static final String HOSTING_TYPE_TOP_ACTIVITY = "top-activity";
+ public static final String HOSTING_TYPE_EMPTY = "";
+
+ private @NonNull final String mHostingType;
private final String mHostingName;
private final int mHostingZygote;
private final String mDefiningPackageName;
private final int mDefiningUid;
private final boolean mIsTopApp;
private final String mDefiningProcessName;
+ @Nullable private final String mAction;
- public HostingRecord(String hostingType) {
+ public HostingRecord(@NonNull String hostingType) {
this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
- -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
+ -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */,
+ null /* action */);
}
- public HostingRecord(String hostingType, ComponentName hostingName) {
+ public HostingRecord(@NonNull String hostingType, ComponentName hostingName) {
this(hostingType, hostingName, REGULAR_ZYGOTE);
}
- public HostingRecord(String hostingType, ComponentName hostingName, String definingPackageName,
- int definingUid, String definingProcessName) {
- this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
- definingUid, false /* isTopApp */, definingProcessName);
+ public HostingRecord(@NonNull String hostingType, ComponentName hostingName,
+ @Nullable String action) {
+ this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
+ null /* definingPackageName */, -1 /* mDefiningUid */, false /* isTopApp */,
+ null /* definingProcessName */, action);
}
- public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
+ public HostingRecord(@NonNull String hostingType, ComponentName hostingName,
+ String definingPackageName, int definingUid, String definingProcessName) {
+ this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
+ definingUid, false /* isTopApp */, definingProcessName, null /* action */);
+ }
+
+ public HostingRecord(@NonNull String hostingType, ComponentName hostingName, boolean isTopApp) {
this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */,
- null /* definingProcessName */);
+ null /* definingProcessName */, null /* action */);
}
- public HostingRecord(String hostingType, String hostingName) {
+ public HostingRecord(@NonNull String hostingType, String hostingName) {
this(hostingType, hostingName, REGULAR_ZYGOTE);
}
- private HostingRecord(String hostingType, ComponentName hostingName, int hostingZygote) {
+ private HostingRecord(@NonNull String hostingType, ComponentName hostingName,
+ int hostingZygote) {
this(hostingType, hostingName.toShortString(), hostingZygote);
}
- private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
+ private HostingRecord(@NonNull String hostingType, String hostingName, int hostingZygote) {
this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
- -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
+ -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */,
+ null /* action */);
}
- private HostingRecord(String hostingType, String hostingName, int hostingZygote,
+ private HostingRecord(@NonNull String hostingType, String hostingName, int hostingZygote,
String definingPackageName, int definingUid, boolean isTopApp,
- String definingProcessName) {
+ String definingProcessName, @Nullable String action) {
mHostingType = hostingType;
mHostingName = hostingName;
mHostingZygote = hostingZygote;
@@ -102,9 +134,10 @@
mDefiningUid = definingUid;
mIsTopApp = isTopApp;
mDefiningProcessName = definingProcessName;
+ mAction = action;
}
- public String getType() {
+ public @NonNull String getType() {
return mHostingType;
}
@@ -147,14 +180,24 @@
}
/**
+ * Returns the broadcast's intent action if the process is started for a broadcast receiver.
+ *
+ * @return the intent action of the broadcast.
+ */
+ public @Nullable String getAction() {
+ return mAction;
+ }
+
+ /**
* Creates a HostingRecord for a process that must spawn from the webview zygote
* @param hostingName name of the component to be hosted in this process
* @return The constructed HostingRecord
*/
public static HostingRecord byWebviewZygote(ComponentName hostingName,
String definingPackageName, int definingUid, String definingProcessName) {
- return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE,
- definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
+ return new HostingRecord(HostingRecord.HOSTING_TYPE_EMPTY, hostingName.toShortString(),
+ WEBVIEW_ZYGOTE, definingPackageName, definingUid, false /* isTopApp */,
+ definingProcessName, null /* action */);
}
/**
@@ -166,8 +209,9 @@
*/
public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
int definingUid, String definingProcessName) {
- return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
- definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
+ return new HostingRecord(HostingRecord.HOSTING_TYPE_EMPTY, hostingName.toShortString(),
+ APP_ZYGOTE, definingPackageName, definingUid, false /* isTopApp */,
+ definingProcessName, null /* action */);
}
/**
@@ -183,4 +227,44 @@
public boolean usesWebviewZygote() {
return mHostingZygote == WEBVIEW_ZYGOTE;
}
+
+ /**
+ * Map the string hostingType to enum HostingType defined in ProcessStartTime proto.
+ * @param hostingType
+ * @return enum HostingType defined in ProcessStartTime proto
+ */
+ public static int getHostingTypeIdStatsd(@NonNull String hostingType) {
+ switch(hostingType) {
+ case HOSTING_TYPE_ACTIVITY:
+ return ProcessStartTime.HOSTING_TYPE_ACTIVITY;
+ case HOSTING_TYPE_ADDED_APPLICATION:
+ return ProcessStartTime.HOSTING_TYPE_ADDED_APPLICATION;
+ case HOSTING_TYPE_BACKUP:
+ return ProcessStartTime.HOSTING_TYPE_BACKUP;
+ case HOSTING_TYPE_BROADCAST:
+ return ProcessStartTime.HOSTING_TYPE_BROADCAST;
+ case HOSTING_TYPE_CONTENT_PROVIDER:
+ return ProcessStartTime.HOSTING_TYPE_CONTENT_PROVIDER;
+ case HOSTING_TYPE_LINK_FAIL:
+ return ProcessStartTime.HOSTING_TYPE_LINK_FAIL;
+ case HOSTING_TYPE_ON_HOLD:
+ return ProcessStartTime.HOSTING_TYPE_ON_HOLD;
+ case HOSTING_TYPE_NEXT_ACTIVITY:
+ return ProcessStartTime.HOSTING_TYPE_NEXT_ACTIVITY;
+ case HOSTING_TYPE_NEXT_TOP_ACTIVITY:
+ return ProcessStartTime.HOSTING_TYPE_NEXT_TOP_ACTIVITY;
+ case HOSTING_TYPE_RESTART:
+ return ProcessStartTime.HOSTING_TYPE_RESTART;
+ case HOSTING_TYPE_SERVICE:
+ return ProcessStartTime.HOSTING_TYPE_SERVICE;
+ case HOSTING_TYPE_SYSTEM:
+ return ProcessStartTime.HOSTING_TYPE_SYSTEM;
+ case HOSTING_TYPE_TOP_ACTIVITY:
+ return ProcessStartTime.HOSTING_TYPE_TOP_ACTIVITY;
+ case HOSTING_TYPE_EMPTY:
+ return ProcessStartTime.HOSTING_TYPE_EMPTY;
+ default:
+ return ProcessStartTime.HOSTING_TYPE_UNKNOWN;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ProcessProfileRecord.java b/services/core/java/com/android/server/am/ProcessProfileRecord.java
index 50970b5..cee34d5 100644
--- a/services/core/java/com/android/server/am/ProcessProfileRecord.java
+++ b/services/core/java/com/android/server/am/ProcessProfileRecord.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.processStateAmToProto;
+import android.annotation.IntDef;
import android.app.IApplicationThread;
import android.content.pm.ApplicationInfo;
import android.os.Debug;
@@ -35,12 +36,95 @@
import com.android.server.am.ProcessList.ProcStateMemTracker;
import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Profiling info of the process, such as PSS, cpu, etc.
*/
final class ProcessProfileRecord {
+ // Keep below types in sync with the HostingComponentType in the atoms.proto.
+ /**
+ * The type of the component this process is hosting;
+ * this means not hosting any components (cached).
+ */
+ static final int HOSTING_COMPONENT_TYPE_EMPTY = 0x0;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's a system process.
+ */
+ static final int HOSTING_COMPONENT_TYPE_SYSTEM = 0x00000001;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's a persistent process.
+ */
+ static final int HOSTING_COMPONENT_TYPE_PERSISTENT = 0x00000002;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting a backup/restore agent.
+ */
+ static final int HOSTING_COMPONENT_TYPE_BACKUP = 0x00000004;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting an instrumentation.
+ */
+ static final int HOSTING_COMPONENT_TYPE_INSTRUMENTATION = 0x00000008;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting an activity.
+ */
+ static final int HOSTING_COMPONENT_TYPE_ACTIVITY = 0x00000010;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting a broadcast receiver.
+ */
+ static final int HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER = 0x00000020;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting a content provider.
+ */
+ static final int HOSTING_COMPONENT_TYPE_PROVIDER = 0x00000040;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting a started service.
+ */
+ static final int HOSTING_COMPONENT_TYPE_STARTED_SERVICE = 0x00000080;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's hosting a foreground service.
+ */
+ static final int HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE = 0x00000100;
+
+ /**
+ * The type of the component this process is hosting;
+ * this means it's being bound via a service binding.
+ */
+ static final int HOSTING_COMPONENT_TYPE_BOUND_SERVICE = 0x00000200;
+
+ @IntDef(flag = true, prefix = { "HOSTING_COMPONENT_TYPE_" }, value = {
+ HOSTING_COMPONENT_TYPE_EMPTY,
+ HOSTING_COMPONENT_TYPE_SYSTEM,
+ HOSTING_COMPONENT_TYPE_PERSISTENT,
+ HOSTING_COMPONENT_TYPE_BACKUP,
+ HOSTING_COMPONENT_TYPE_INSTRUMENTATION,
+ HOSTING_COMPONENT_TYPE_ACTIVITY,
+ HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER,
+ HOSTING_COMPONENT_TYPE_PROVIDER,
+ HOSTING_COMPONENT_TYPE_STARTED_SERVICE,
+ HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE,
+ HOSTING_COMPONENT_TYPE_BOUND_SERVICE,
+ })
+ @interface HostingComponentType {}
+
final ProcessRecord mApp;
private final ActivityManagerService mService;
@@ -194,6 +278,12 @@
@GuardedBy("mProfilerLock")
private long mLastStateTime;
+ private AtomicInteger mCurrentHostingComponentTypes =
+ new AtomicInteger(HOSTING_COMPONENT_TYPE_EMPTY);
+
+ private AtomicInteger mHistoricalHostingComponentTypes =
+ new AtomicInteger(HOSTING_COMPONENT_TYPE_EMPTY);
+
private final ActivityManagerGlobalLock mProcLock;
ProcessProfileRecord(final ProcessRecord app) {
@@ -292,6 +382,8 @@
mThread = null;
}
}
+ mCurrentHostingComponentTypes.set(HOSTING_COMPONENT_TYPE_EMPTY);
+ mHistoricalHostingComponentTypes.set(HOSTING_COMPONENT_TYPE_EMPTY);
}
@GuardedBy("mProfilerLock")
@@ -605,6 +697,23 @@
mLastStateTime = state.getLastStateTime();
}
+ void addHostingComponentType(@HostingComponentType int type) {
+ mCurrentHostingComponentTypes.set(mCurrentHostingComponentTypes.get() | type);
+ mHistoricalHostingComponentTypes.set(mHistoricalHostingComponentTypes.get() | type);
+ }
+
+ void clearHostingComponentType(@HostingComponentType int type) {
+ mCurrentHostingComponentTypes.set(mCurrentHostingComponentTypes.get() & ~type);
+ }
+
+ @HostingComponentType int getCurrentHostingComponentTypes() {
+ return mCurrentHostingComponentTypes.get();
+ }
+
+ @HostingComponentType int getHistoricalHostingComponentTypes() {
+ return mHistoricalHostingComponentTypes.get();
+ }
+
@GuardedBy("mService")
void dumpPss(PrintWriter pw, String prefix, long nowUptime) {
synchronized (mProfilerLock) {
@@ -643,6 +752,11 @@
pw.print(" reportLowMemory=");
pw.println(mReportLowMemory);
}
+ pw.print(prefix);
+ pw.print("currentHostingComponentTypes=0x");
+ pw.print(Integer.toHexString(getCurrentHostingComponentTypes()));
+ pw.print(" historicalHostingComponentTypes=0x");
+ pw.println(Integer.toHexString(getHistoricalHostingComponentTypes()));
}
void dumpCputime(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 6b748193..486c8ed 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BOUND_SERVICE;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE;
+
import android.app.ActivityManager;
import android.content.Context;
import android.os.IBinder;
@@ -141,6 +144,11 @@
mHasForegroundServices = hasForegroundServices;
mFgServiceTypes = fgServiceTypes;
mApp.getWindowProcessController().setHasForegroundServices(hasForegroundServices);
+ if (hasForegroundServices) {
+ mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
+ } else {
+ mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
+ }
}
boolean hasForegroundServices() {
@@ -295,6 +303,7 @@
boolean added = mServices.add(record);
if (added && record.serviceInfo != null) {
mApp.getWindowProcessController().onServiceStarted(record.serviceInfo);
+ updateHostingComonentTypeForBindingsLocked();
}
if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max(
@@ -318,6 +327,9 @@
if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
updateHasTopStartedAlmostPerceptibleServices();
}
+ if (removed) {
+ updateHostingComonentTypeForBindingsLocked();
+ }
return removed;
}
@@ -437,6 +449,23 @@
}
@GuardedBy("mService")
+ void updateHostingComonentTypeForBindingsLocked() {
+ boolean hasBoundClient = false;
+ for (int i = numberOfRunningServices() - 1; i >= 0; i--) {
+ final ServiceRecord sr = getRunningServiceAt(i);
+ if (sr != null && !sr.getConnections().isEmpty()) {
+ hasBoundClient = true;
+ break;
+ }
+ }
+ if (hasBoundClient) {
+ mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
+ } else {
+ mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
+ }
+ }
+
+ @GuardedBy("mService")
boolean incServiceCrashCountLocked(long now) {
final boolean procIsBoundForeground = mApp.mState.getCurProcState()
== ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index e0660b4..262436d 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -21,6 +21,9 @@
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_ACTIVITY;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_STARTED_SERVICE;
import static com.android.server.am.ProcessRecord.TAG;
import android.annotation.ElapsedRealtimeLong;
@@ -694,6 +697,11 @@
@GuardedBy("mProcLock")
void setHasStartedServices(boolean hasStartedServices) {
mHasStartedServices = hasStartedServices;
+ if (hasStartedServices) {
+ mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
+ } else {
+ mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
+ }
}
@GuardedBy("mProcLock")
@@ -999,6 +1007,11 @@
if (mCachedHasActivities == VALUE_INVALID) {
mCachedHasActivities = mApp.getWindowProcessController().hasActivities() ? VALUE_TRUE
: VALUE_FALSE;
+ if (mCachedHasActivities == VALUE_TRUE) {
+ mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_ACTIVITY);
+ } else {
+ mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_ACTIVITY);
+ }
}
return mCachedHasActivities == VALUE_TRUE;
}
@@ -1065,6 +1078,9 @@
if (mCachedIsReceivingBroadcast == VALUE_TRUE) {
mCachedSchedGroup = tmpQueue.contains(mService.mFgBroadcastQueue)
? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
+ mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER);
+ } else {
+ mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER);
}
}
return mCachedIsReceivingBroadcast == VALUE_TRUE;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 480e69b..4b82ad8 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -23,6 +23,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BOUND_SERVICE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -693,6 +694,7 @@
app.removeAllowBackgroundActivityStartsToken(this);
}
app.mServices.updateBoundClientUids();
+ app.mServices.updateHostingComonentTypeForBindingsLocked();
}
app = proc;
if (pendingConnectionGroup > 0 && proc != null) {
@@ -717,6 +719,7 @@
}
if (proc != null) {
proc.mServices.updateBoundClientUids();
+ proc.mServices.updateHostingComonentTypeForBindingsLocked();
}
}
@@ -736,6 +739,7 @@
// if we have a process attached, add bound client uid of this connection to it
if (app != null) {
app.mServices.addBoundClientUid(c.clientUid);
+ app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
}
}
@@ -744,6 +748,7 @@
// if we have a process attached, tell it to update the state of bound clients
if (app != null) {
app.mServices.updateBoundClientUids();
+ app.mServices.updateHostingComonentTypeForBindingsLocked();
}
}
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index b9efdf5..574a3e7 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -192,10 +192,13 @@
private final int mSubId;
private long mQuota;
- /** Current multipath budget. Nonzero iff we have budget and a UsageCallback is armed. */
- private long mMultipathBudget;
+ /** Current multipath budget. Nonzero iff we have budget. */
+ // The budget could be accessed by multiple threads, make it volatile to ensure the callers
+ // on a different thread will not see the stale value.
+ private volatile long mMultipathBudget;
private final NetworkTemplate mNetworkTemplate;
private final UsageCallback mUsageCallback;
+ private boolean mUsageCallbackRegistered = false;
private NetworkCapabilities mNetworkCapabilities;
private final NetworkStatsManager mStatsManager;
@@ -234,7 +237,6 @@
@Override
public void onThresholdReached(int networkType, String subscriberId) {
if (DBG) Log.d(TAG, "onThresholdReached for network " + network);
- mMultipathBudget = 0;
updateMultipathBudget();
}
};
@@ -376,9 +378,9 @@
if (DBG) {
Log.d(TAG, "Setting callback for " + budget + " bytes on network " + network);
}
- registerUsageCallback(budget);
+ setMultipathBudget(budget);
} else {
- maybeUnregisterUsageCallback();
+ clearMultipathBudget();
}
}
@@ -403,23 +405,30 @@
return mMultipathBudget > 0;
}
- private void registerUsageCallback(long budget) {
+ // Sets the budget and registers a usage callback for it.
+ private void setMultipathBudget(long budget) {
maybeUnregisterUsageCallback();
+ if (DBG) Log.d(TAG, "Registering callback, budget is " + mMultipathBudget);
mStatsManager.registerUsageCallback(mNetworkTemplate, budget,
(command) -> mHandler.post(command), mUsageCallback);
+ mUsageCallbackRegistered = true;
mMultipathBudget = budget;
}
private void maybeUnregisterUsageCallback() {
- if (haveMultipathBudget()) {
- if (DBG) Log.d(TAG, "Unregistering callback, budget was " + mMultipathBudget);
- mStatsManager.unregisterUsageCallback(mUsageCallback);
- mMultipathBudget = 0;
- }
+ if (!mUsageCallbackRegistered) return;
+ if (DBG) Log.d(TAG, "Unregistering callback, budget was " + mMultipathBudget);
+ mStatsManager.unregisterUsageCallback(mUsageCallback);
+ mUsageCallbackRegistered = false;
+ }
+
+ private void clearMultipathBudget() {
+ maybeUnregisterUsageCallback();
+ mMultipathBudget = 0;
}
void shutdown() {
- maybeUnregisterUsageCallback();
+ clearMultipathBudget();
}
}
diff --git a/services/core/java/com/android/server/connectivity/PacProxyService.java b/services/core/java/com/android/server/connectivity/PacProxyService.java
index 3a97765..2e90a3d8 100644
--- a/services/core/java/com/android/server/connectivity/PacProxyService.java
+++ b/services/core/java/com/android/server/connectivity/PacProxyService.java
@@ -44,6 +44,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
+import android.webkit.URLUtil;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.TrafficStatsConstants;
@@ -232,8 +233,22 @@
* @throws IOException if the URL is malformed, or the PAC file is too big.
*/
private static String get(Uri pacUri) throws IOException {
- URL url = new URL(pacUri.toString());
- URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
+ if (!URLUtil.isValidUrl(pacUri.toString())) {
+ throw new IOException("Malformed URL:" + pacUri);
+ }
+
+ final URL url = new URL(pacUri.toString());
+ URLConnection urlConnection;
+ try {
+ urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
+ // Catch the possible exceptions and rethrow as IOException to not to crash the system
+ // for illegal input.
+ } catch (IllegalArgumentException e) {
+ throw new IOException("Incorrect proxy type for " + pacUri);
+ } catch (UnsupportedOperationException e) {
+ throw new IOException("Unsupported URL connection type for " + pacUri);
+ }
+
long contentLength = -1;
try {
contentLength = Long.parseLong(urlConnection.getHeaderField("Content-Length"));
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index ca7b789..7448611 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -102,13 +102,15 @@
return;
}
synchronized (mSyncRoot) {
- if (brightness == mBrightness) {
- return;
+ // If the brightness is the same, we still need to update any listeners as the act of
+ // setting the brightness alone has side effects, like clearing any temporary
+ // brightness. We can skip persisting to disk, however, since it hasn't actually
+ // changed.
+ if (brightness != mBrightness) {
+ mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
+ brightness);
}
-
mBrightness = brightness;
- mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
- brightness);
int toSend = Float.floatToIntBits(mBrightness);
Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED, toSend, 0);
mHandler.sendMessage(msg);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ec7ccc4..6285ef1 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -3349,7 +3349,7 @@
synchronized (mSyncRoot) {
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.putScreenBrightnessSetting(brightness);
+ dpc.setBrightness(brightness);
}
mPersistentDataStore.saveIfNeeded();
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index d13a9a3..f39c412 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1345,7 +1345,7 @@
if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
slowChange = true; // slowly adapt to auto-brightness
}
- updateScreenBrightnessSetting = true;
+ updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
mAppliedAutoBrightness = true;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
} else {
@@ -1415,7 +1415,7 @@
// before applying the low power or dim transformations so that the slider
// accurately represents the full possible range, even if they range changes what
// it means in absolute terms.
- putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true);
+ updateScreenBrightnessSetting(brightnessState);
}
// Apply dimming by at least some minimum amount when user activity
@@ -2288,17 +2288,18 @@
return clampScreenBrightnessForVr(brightnessFloat);
}
- void putScreenBrightnessSetting(float brightnessValue) {
- putScreenBrightnessSetting(brightnessValue, false);
+ void setBrightness(float brightnessValue) {
+ // Update the setting, which will eventually call back into DPC to have us actually update
+ // the display with the new value.
+ mBrightnessSetting.setBrightness(brightnessValue);
}
- private void putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent) {
- if (!isValidBrightnessValue(brightnessValue)) {
+ private void updateScreenBrightnessSetting(float brightnessValue) {
+ if (!isValidBrightnessValue(brightnessValue)
+ || brightnessValue == mCurrentScreenBrightnessSetting) {
return;
}
- if (updateCurrent) {
- setCurrentScreenBrightness(brightnessValue);
- }
+ setCurrentScreenBrightness(brightnessValue);
mBrightnessSetting.setBrightness(brightnessValue);
}
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 2eba080..59daee9 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -20,6 +20,7 @@
import android.graphics.Point;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.WifiDisplay;
+import android.os.Handler;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
@@ -31,12 +32,14 @@
import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -141,13 +144,22 @@
// The interface for methods which should be replaced by the test harness.
private Injector mInjector;
+ private final Handler mHandler;
+ private final Object mFileAccessLock = new Object();
+
public PersistentDataStore() {
this(new Injector());
}
@VisibleForTesting
PersistentDataStore(Injector injector) {
+ this(injector, BackgroundThread.getHandler());
+ }
+
+ @VisibleForTesting
+ PersistentDataStore(Injector injector, Handler handler) {
mInjector = injector;
+ mHandler = handler;
}
public void saveIfNeeded() {
@@ -418,45 +430,60 @@
}
private void load() {
- clearState();
-
- final InputStream is;
- try {
- is = mInjector.openRead();
- } catch (FileNotFoundException ex) {
- return;
- }
-
- TypedXmlPullParser parser;
- try {
- parser = Xml.resolvePullParser(is);
- loadFromXml(parser);
- } catch (IOException ex) {
- Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
+ synchronized (mFileAccessLock) {
clearState();
- } catch (XmlPullParserException ex) {
- Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
- clearState();
- } finally {
- IoUtils.closeQuietly(is);
+
+ final InputStream is;
+ try {
+ is = mInjector.openRead();
+ } catch (FileNotFoundException ex) {
+ return;
+ }
+
+ TypedXmlPullParser parser;
+ try {
+ parser = Xml.resolvePullParser(is);
+ loadFromXml(parser);
+ } catch (IOException ex) {
+ Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
+ clearState();
+ } catch (XmlPullParserException ex) {
+ Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
+ clearState();
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
}
}
private void save() {
- final OutputStream os;
+ final ByteArrayOutputStream os;
try {
- os = mInjector.startWrite();
- boolean success = false;
- try {
- TypedXmlSerializer serializer = Xml.resolveSerializer(os);
- saveToXml(serializer);
- serializer.flush();
- success = true;
- } finally {
- mInjector.finishWrite(os, success);
- }
+ os = new ByteArrayOutputStream();
+
+ TypedXmlSerializer serializer = Xml.resolveSerializer(os);
+ saveToXml(serializer);
+ serializer.flush();
+
+ mHandler.removeCallbacksAndMessages(/* token */ null);
+ mHandler.post(() -> {
+ synchronized (mFileAccessLock) {
+ OutputStream fileOutput = null;
+ try {
+ fileOutput = mInjector.startWrite();
+ os.writeTo(fileOutput);
+ fileOutput.flush();
+ } catch (IOException ex) {
+ Slog.w(TAG, "Failed to save display manager persistent store data.", ex);
+ } finally {
+ if (fileOutput != null) {
+ mInjector.finishWrite(fileOutput, true);
+ }
+ }
+ }
+ });
} catch (IOException ex) {
- Slog.w(TAG, "Failed to save display manager persistent store data.", ex);
+ Slog.w(TAG, "Failed to process the XML serializer.", ex);
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index 2e1aaf8..aba7572 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -599,6 +599,7 @@
SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS);
} catch (RuntimeException e) {
Log.e(TAG, "Failed to request network.", e);
+ mSuplConnectivityCallback = null;
handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
}
}
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index 78e7b0a..7ca1978 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -321,6 +321,9 @@
|| targetPkgSetting.getAppId() < Process.FIRST_APPLICATION_UID
|| callingAppId == targetPkgSetting.getAppId()) {
return false;
+ } else if (Process.isSdkSandboxUid(callingAppId)) {
+ // we only allow sdk sandbox processes access to forcequeryable packages
+ return !isForceQueryable(targetPkgSetting.getAppId());
}
if (mCacheReady) { // use cache
if (!shouldFilterApplicationUsingCache(callingUid,
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 719c3b7..6afc5890 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -36,6 +36,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.ActivityManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.Context;
@@ -1089,12 +1090,6 @@
PlatformCompat compat, ComponentResolverApi resolver,
List<ResolveInfo> resolveInfos, boolean isReceiver,
Intent intent, String resolvedType, int filterCallingUid) {
- // Do not enforce filter matching when the caller is system or root.
- // see ActivityManager#checkComponentPermission(String, int, int, boolean)
- if (filterCallingUid == Process.ROOT_UID || filterCallingUid == Process.SYSTEM_UID) {
- return;
- }
-
final Printer logPrinter = DEBUG_INTENT_MATCHING
? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM)
: null;
@@ -1102,8 +1097,9 @@
for (int i = resolveInfos.size() - 1; i >= 0; --i) {
final ComponentInfo info = resolveInfos.get(i).getComponentInfo();
- // Do not enforce filter matching when the caller is the same app
- if (info.applicationInfo.uid == filterCallingUid) {
+ // Do not enforce filter matching when the caller is system, root, or the same app
+ if (ActivityManager.checkComponentPermission(null, filterCallingUid,
+ info.applicationInfo.uid, false) == PackageManager.PERMISSION_GRANTED) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index 6e5011d..3b4aa8e 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -154,7 +154,7 @@
for (InputWindowHandle window : windowHandles) {
final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
- if (visible && window.getWindow() != null) {
+ if (visible && window.getWindow() != null && !window.isClone) {
tempVisibleWindows.add(window);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 7723a46..fb87576 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -192,6 +192,7 @@
private Task mInTask;
private TaskFragment mInTaskFragment;
+ private TaskFragment mAddingToTaskFragment;
@VisibleForTesting
boolean mAddingToTask;
@@ -2254,20 +2255,27 @@
// In this situation we want to remove all activities from the task up to the one
// being started. In most cases this means we are resetting the task to its initial
// state.
- final ActivityRecord top = targetTask.performClearTop(mStartActivity, mLaunchFlags);
+ final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity,
+ mLaunchFlags);
- if (top != null) {
- if (top.isRootOfTask()) {
+ if (clearTop != null && !clearTop.finishing) {
+ if (clearTop.isRootOfTask()) {
// Activity aliases may mean we use different intents for the top activity,
// so make sure the task now has the identity of the new intent.
- top.getTask().setIntent(mStartActivity);
+ clearTop.getTask().setIntent(mStartActivity);
}
- deliverNewIntent(top, intentGrants);
+ deliverNewIntent(clearTop, intentGrants);
} else {
// A special case: we need to start the activity because it is not currently
// running, and the caller has asked to clear the current task to have this
// activity at the top.
mAddingToTask = true;
+ // Adding the new activity to the same embedded TF of the clear-top activity if
+ // possible.
+ if (clearTop != null && clearTop.getTaskFragment() != null
+ && clearTop.getTaskFragment().isEmbedded()) {
+ mAddingToTaskFragment = clearTop.getTaskFragment();
+ }
if (targetTask.getRootTask() == null) {
// Target root task got cleared when we all activities were removed above.
// Go ahead and reset it.
@@ -2892,14 +2900,19 @@
newParent = mInTaskFragment;
}
} else {
- final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */,
- false /* includingEmbeddedTask */);
- final TaskFragment taskFragment = top != null ? top.getTaskFragment() : null;
- if (taskFragment != null && taskFragment.isEmbedded()
- && canEmbedActivity(taskFragment, mStartActivity, false /* newTask */, task)) {
+ TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null;
+ if (candidateTf == null) {
+ final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */,
+ false /* includingEmbeddedTask */);
+ if (top != null) {
+ candidateTf = top.getTaskFragment();
+ }
+ }
+ if (candidateTf != null && candidateTf.isEmbedded()
+ && canEmbedActivity(candidateTf, mStartActivity, false /* newTask */, task)) {
// Use the embedded TaskFragment of the top activity as the new parent if the
// activity can be embedded.
- newParent = top.getTaskFragment();
+ newParent = candidateTf;
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 95de040..35f977d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -146,6 +146,7 @@
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
+import com.android.server.am.HostingRecord;
import com.android.server.am.UserState;
import com.android.server.utils.Slogf;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
@@ -1056,7 +1057,9 @@
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
- mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
+ mService.startProcessAsync(r, knownToBeDead, isTop,
+ isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
+ : HostingRecord.HOSTING_TYPE_ACTIVITY);
}
boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho,
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index fa506ca..140ac33 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -76,6 +76,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Trace;
import android.util.ArrayMap;
@@ -145,7 +146,8 @@
* Returns the currently visible window that is associated with the wallpaper in case we are
* transitioning from an activity with a wallpaper to one without.
*/
- private @Nullable WindowState getOldWallpaper() {
+ @Nullable
+ private WindowState getOldWallpaper() {
final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
final @TransitionType int firstTransit =
mDisplayContent.mAppTransition.getFirstAppTransition();
@@ -165,6 +167,16 @@
? null : wallpaperTarget;
}
+ @NonNull
+ private static ArraySet<ActivityRecord> getAppsForAnimation(
+ @NonNull ArraySet<ActivityRecord> apps, boolean excludeLauncherFromAnimation) {
+ final ArraySet<ActivityRecord> appsForAnimation = new ArraySet<>(apps);
+ if (excludeLauncherFromAnimation) {
+ appsForAnimation.removeIf(ConfigurationContainer::isActivityTypeHome);
+ }
+ return appsForAnimation;
+ }
+
/**
* Handle application transition for given display.
*/
@@ -214,18 +226,29 @@
mWallpaperControllerLocked.adjustWallpaperWindowsForAppTransitionIfNeeded(
mDisplayContent.mOpeningApps);
- final @TransitionOldType int transit = getTransitCompatType(
- mDisplayContent.mAppTransition, mDisplayContent.mOpeningApps,
- mDisplayContent.mClosingApps, mDisplayContent.mChangingContainers,
+ // Remove launcher from app transition animation while recents is running. Recents animation
+ // is managed outside of app transition framework, so we just need to commit visibility.
+ final boolean excludeLauncherFromAnimation =
+ mDisplayContent.mOpeningApps.stream().anyMatch(
+ (app) -> app.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS))
+ || mDisplayContent.mClosingApps.stream().anyMatch(
+ (app) -> app.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS));
+ final ArraySet<ActivityRecord> openingAppsForAnimation = getAppsForAnimation(
+ mDisplayContent.mOpeningApps, excludeLauncherFromAnimation);
+ final ArraySet<ActivityRecord> closingAppsForAnimation = getAppsForAnimation(
+ mDisplayContent.mClosingApps, excludeLauncherFromAnimation);
+
+ @TransitionOldType final int transit = getTransitCompatType(
+ mDisplayContent.mAppTransition, openingAppsForAnimation, closingAppsForAnimation,
+ mDisplayContent.mChangingContainers,
mWallpaperControllerLocked.getWallpaperTarget(), getOldWallpaper(),
mDisplayContent.mSkipAppTransitionAnimation);
mDisplayContent.mSkipAppTransitionAnimation = false;
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"handleAppTransitionReady: displayId=%d appTransition={%s}"
- + " openingApps=[%s] closingApps=[%s] transit=%s",
- mDisplayContent.mDisplayId,
- appTransition.toString(),
+ + " excludeLauncherFromAnimation=%b openingApps=[%s] closingApps=[%s] transit=%s",
+ mDisplayContent.mDisplayId, appTransition.toString(), excludeLauncherFromAnimation,
mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
AppTransition.appTransitionOldToString(transit));
@@ -233,13 +256,15 @@
// what will control the animation theme. If all closing windows are obscured, then there is
// no need to do an animation. This is the case, for example, when this transition is being
// done behind a dream window.
- final ArraySet<Integer> activityTypes = collectActivityTypes(mDisplayContent.mOpeningApps,
- mDisplayContent.mClosingApps, mDisplayContent.mChangingContainers);
- final ActivityRecord animLpActivity = findAnimLayoutParamsToken(transit, activityTypes);
+ final ArraySet<Integer> activityTypes = collectActivityTypes(openingAppsForAnimation,
+ closingAppsForAnimation, mDisplayContent.mChangingContainers);
+ final ActivityRecord animLpActivity = findAnimLayoutParamsToken(transit, activityTypes,
+ openingAppsForAnimation, closingAppsForAnimation,
+ mDisplayContent.mChangingContainers);
final ActivityRecord topOpeningApp =
- getTopApp(mDisplayContent.mOpeningApps, false /* ignoreHidden */);
+ getTopApp(openingAppsForAnimation, false /* ignoreHidden */);
final ActivityRecord topClosingApp =
- getTopApp(mDisplayContent.mClosingApps, false /* ignoreHidden */);
+ getTopApp(closingAppsForAnimation, false /* ignoreHidden */);
final ActivityRecord topChangingApp =
getTopApp(mDisplayContent.mChangingContainers, false /* ignoreHidden */);
final WindowManager.LayoutParams animLp = getAnimLp(animLpActivity);
@@ -251,14 +276,14 @@
overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
}
- final boolean voiceInteraction = containsVoiceInteraction(mDisplayContent.mClosingApps)
- || containsVoiceInteraction(mDisplayContent.mOpeningApps);
+ final boolean voiceInteraction = containsVoiceInteraction(closingAppsForAnimation)
+ || containsVoiceInteraction(openingAppsForAnimation);
final int layoutRedo;
mService.mSurfaceAnimationRunner.deferStartingAnimations();
try {
- applyAnimations(mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps, transit,
- animLp, voiceInteraction);
+ applyAnimations(openingAppsForAnimation, closingAppsForAnimation, transit, animLp,
+ voiceInteraction);
handleClosingApps();
handleOpeningApps();
handleChangingApps(transit);
@@ -310,7 +335,7 @@
* case we are transitioning from an activity with a wallpaper to one
* without. Otherwise null.
*/
- static @TransitionOldType int getTransitCompatType(AppTransition appTransition,
+ @TransitionOldType static int getTransitCompatType(AppTransition appTransition,
ArraySet<ActivityRecord> openingApps, ArraySet<ActivityRecord> closingApps,
ArraySet<WindowContainer> changingContainers, @Nullable WindowState wallpaperTarget,
@Nullable WindowState oldWallpaper, boolean skipAppTransitionAnimation) {
@@ -341,8 +366,8 @@
if (skipAppTransitionAnimation) {
return WindowManager.TRANSIT_OLD_UNSET;
}
- final @TransitionFlags int flags = appTransition.getTransitFlags();
- final @TransitionType int firstTransit = appTransition.getFirstAppTransition();
+ @TransitionFlags final int flags = appTransition.getTransitFlags();
+ @TransitionType final int firstTransit = appTransition.getFirstAppTransition();
// Special transitions
// TODO(new-app-transitions): Revisit if those can be rewritten by using flags.
@@ -720,11 +745,9 @@
*/
@Nullable
private ActivityRecord findAnimLayoutParamsToken(@TransitionOldType int transit,
- ArraySet<Integer> activityTypes) {
+ ArraySet<Integer> activityTypes, ArraySet<ActivityRecord> openingApps,
+ ArraySet<ActivityRecord> closingApps, ArraySet<WindowContainer> changingApps) {
ActivityRecord result;
- final ArraySet<ActivityRecord> closingApps = mDisplayContent.mClosingApps;
- final ArraySet<ActivityRecord> openingApps = mDisplayContent.mOpeningApps;
- final ArraySet<WindowContainer> changingApps = mDisplayContent.mChangingContainers;
// Remote animations always win, but fullscreen tokens override non-fullscreen tokens.
result = lookForHighestTokenWithFilter(closingApps, openingApps, changingApps,
@@ -1152,11 +1175,6 @@
if (activity == null) {
continue;
}
- if (activity.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) {
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
- "Delaying app transition for recents animation to finish");
- return false;
- }
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Check opening app=%s: allDrawn=%b startingDisplayed=%b "
+ "startingMoved=%b isRelaunching()=%b startingWindow=%s",
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 1bec2a5..bf5246f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1644,7 +1644,7 @@
* activities on top of it and return the instance.
*
* @param newR Description of the new activity being started.
- * @return Returns the old activity that should be continued to be used,
+ * @return Returns the existing activity in the task that performs the clear-top operation,
* or {@code null} if none was found.
*/
private ActivityRecord clearTopActivities(ActivityRecord newR, int launchFlags) {
@@ -1663,7 +1663,6 @@
&& !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
if (!r.finishing) {
r.finishIfPossible("clear-task-top", false /* oomAdj */);
- return null;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 324f029..eca0fd7 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -96,6 +96,7 @@
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
+import com.android.server.am.HostingRecord;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.FileDescriptor;
@@ -1147,7 +1148,8 @@
// for the current activity to be paused.
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
- isTop ? "pre-top-activity" : "pre-activity");
+ isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
+ : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
@@ -2061,9 +2063,15 @@
final boolean inPipTransition = windowingMode == WINDOWING_MODE_PINNED
&& !mTmpFullBounds.isEmpty() && mTmpFullBounds.equals(parentBounds);
if (WindowConfiguration.isFloating(windowingMode) && !inPipTransition) {
- // For floating tasks, calculate the smallest width from the bounds of the task
+ // For floating tasks, calculate the smallest width from the bounds of the
+ // task, because they should not be affected by insets.
inOutConfig.smallestScreenWidthDp = (int) (
Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
+ } else if (isEmbedded()) {
+ // For embedded TFs, the smallest width should be updated. Otherwise, inherit
+ // from the parent task would result in applications loaded wrong resource.
+ inOutConfig.smallestScreenWidthDp =
+ Math.min(inOutConfig.screenWidthDp, inOutConfig.screenHeightDp);
}
// otherwise, it will just inherit
}
diff --git a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
index 57a9cb2..9fe8609c 100644
--- a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -24,6 +24,8 @@
import android.content.Context;
import android.hardware.display.BrightnessConfiguration;
+import android.os.Handler;
+import android.os.test.TestLooper;
import android.util.Pair;
import androidx.test.InstrumentationRegistry;
@@ -47,11 +49,14 @@
public class PersistentDataStoreTest {
private PersistentDataStore mDataStore;
private TestInjector mInjector;
+ private TestLooper mTestLooper;
@Before
public void setUp() {
mInjector = new TestInjector();
- mDataStore = new PersistentDataStore(mInjector);
+ mTestLooper = new TestLooper();
+ Handler handler = new Handler(mTestLooper.getLooper());
+ mDataStore = new PersistentDataStore(mInjector, handler);
}
@Test
@@ -147,7 +152,7 @@
}
@Test
- public void testStoreAndReloadOfDisplayBrightnessConfigurations() {
+ public void testStoreAndReloadOfDisplayBrightnessConfigurations() throws InterruptedException {
final String uniqueDisplayId = "test:123";
int userSerial = 0;
String packageName = "pdsTestPackage";
@@ -178,6 +183,7 @@
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
mInjector.setWriteStream(baos);
mDataStore.saveIfNeeded();
+ mTestLooper.dispatchAll();
assertTrue(mInjector.wasWriteSuccessful());
TestInjector newInjector = new TestInjector();
PersistentDataStore newDataStore = new PersistentDataStore(newInjector);
@@ -222,7 +228,7 @@
}
@Test
- public void testStoreAndReloadOfBrightnessConfigurations() {
+ public void testStoreAndReloadOfBrightnessConfigurations() throws InterruptedException {
final float[] lux = { 0f, 10f };
final float[] nits = {1f, 100f };
final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
@@ -238,6 +244,7 @@
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
mInjector.setWriteStream(baos);
mDataStore.saveIfNeeded();
+ mTestLooper.dispatchAll();
assertTrue(mInjector.wasWriteSuccessful());
TestInjector newInjector = new TestInjector();
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
index 9674ebd..facbe80 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
@@ -1336,6 +1336,46 @@
}
+ @Test
+ public void testSdkSandbox_canSeeForceQueryable() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
+ mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+
+ int callingUid = 20123;
+ assertTrue(Process.isSdkSandboxUid(callingUid));
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+ null /* callingSetting */, target, SYSTEM_USER));
+ }
+
+ @Test
+ public void testSdkSandbox_cannotSeeNonForceQueryable() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
+ mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_APPID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+
+ int callingUid = 20123;
+ assertTrue(Process.isSdkSandboxUid(callingUid));
+
+ assertTrue(
+ appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+ null /* callingSetting */, target, SYSTEM_USER));
+ }
+
private List<Integer> toList(int[] array) {
ArrayList<Integer> ret = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 3592158..436cf36 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_CHANGE;
@@ -25,6 +27,7 @@
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
@@ -409,38 +412,50 @@
}
@Test
- public void testDelayWhileRecents() {
+ public void testExcludeLauncher() {
final DisplayContent dc = createNewDisplay(Display.STATE_ON);
doReturn(false).when(dc).onDescendantOrientationChanged(any());
final Task task = createTask(dc);
- // Simulate activity1 launches activity2.
+ // Simulate activity1 launches activity2
final ActivityRecord activity1 = createActivityRecord(task);
activity1.setVisible(true);
activity1.mVisibleRequested = false;
activity1.allDrawn = true;
+ dc.mClosingApps.add(activity1);
final ActivityRecord activity2 = createActivityRecord(task);
activity2.setVisible(false);
activity2.mVisibleRequested = true;
activity2.allDrawn = true;
-
- dc.mClosingApps.add(activity1);
dc.mOpeningApps.add(activity2);
dc.prepareAppTransition(TRANSIT_OPEN);
- assertTrue(dc.mAppTransition.containsTransitRequest(TRANSIT_OPEN));
+
+ // Simulate start recents
+ final ActivityRecord homeActivity = createActivityRecord(dc, WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_HOME);
+ homeActivity.setVisible(false);
+ homeActivity.mVisibleRequested = true;
+ homeActivity.allDrawn = true;
+ dc.mOpeningApps.add(homeActivity);
+ dc.prepareAppTransition(TRANSIT_NONE);
+ doReturn(true).when(task)
+ .isSelfAnimating(anyInt(), eq(ANIMATION_TYPE_RECENTS));
// Wait until everything in animation handler get executed to prevent the exiting window
// from being removed during WindowSurfacePlacer Traversal.
waitUntilHandlersIdle();
- // Start recents
- doReturn(true).when(task)
- .isSelfAnimating(anyInt(), eq(ANIMATION_TYPE_RECENTS));
-
dc.mAppTransitionController.handleAppTransitionReady();
- verify(activity1, never()).commitVisibility(anyBoolean(), anyBoolean(), anyBoolean());
- verify(activity2, never()).commitVisibility(anyBoolean(), anyBoolean(), anyBoolean());
+ verify(activity1).commitVisibility(eq(false), anyBoolean(), anyBoolean());
+ verify(activity1).applyAnimation(any(), eq(TRANSIT_OLD_ACTIVITY_OPEN), eq(false),
+ anyBoolean(), any());
+ verify(activity2).commitVisibility(eq(true), anyBoolean(), anyBoolean());
+ verify(activity2).applyAnimation(any(), eq(TRANSIT_OLD_ACTIVITY_OPEN), eq(true),
+ anyBoolean(), any());
+ verify(homeActivity).commitVisibility(eq(true), anyBoolean(), anyBoolean());
+ verify(homeActivity, never()).applyAnimation(any(), anyInt(), anyBoolean(), anyBoolean(),
+ any());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 9304761..202168b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -266,7 +266,7 @@
// Detach from process so the activities can be removed from hierarchy when finishing.
activity1.detachFromProcess();
activity2.detachFromProcess();
- assertNull(task.performClearTop(activity1, 0 /* launchFlags */));
+ assertTrue(task.performClearTop(activity1, 0 /* launchFlags */).finishing);
assertFalse(task.hasChild());
// In real case, the task should be preserved for adding new activity.
assertTrue(task.isAttached());
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
index 7e3990d..7d5be8e 100644
--- a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
@@ -23,15 +23,23 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager.ProcessState;
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
import android.app.usage.BroadcastResponseStats;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.permission.PermissionManager;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongArrayQueue;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.CollectionUtils;
import com.android.internal.util.IndentingPrintWriter;
import java.lang.annotation.Retention;
@@ -71,14 +79,33 @@
private SparseArray<SparseArray<UserBroadcastResponseStats>> mUserResponseStats =
new SparseArray<>();
+ /**
+ * Cache of package names holding exempted roles.
+ *
+ * Contains the mapping of userId -> {roleName -> <packages>} data.
+ */
+ // TODO: Use SparseArrayMap to simplify the logic.
+ @GuardedBy("mLock")
+ private SparseArray<ArrayMap<String, List<String>>> mExemptedRoleHoldersCache =
+ new SparseArray<>();
+ private final OnRoleHoldersChangedListener mRoleHoldersChangedListener =
+ this::onRoleHoldersChanged;
+
private AppStandbyInternal mAppStandby;
private BroadcastResponseStatsLogger mLogger;
+ private RoleManager mRoleManager;
BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby) {
mAppStandby = appStandby;
mLogger = new BroadcastResponseStatsLogger();
}
+ void onSystemServicesReady(Context context) {
+ mRoleManager = context.getSystemService(RoleManager.class);
+ mRoleManager.addOnRoleHoldersChangedListenerAsUser(BackgroundThread.getExecutor(),
+ mRoleHoldersChangedListener, UserHandle.ALL);
+ }
+
// TODO (206518114): Move all callbacks handling to a handler thread.
void reportBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
UserHandle targetUser, long idForResponseEvent,
@@ -86,10 +113,19 @@
mLogger.logBroadcastDispatchEvent(sourceUid, targetPackage, targetUser,
idForResponseEvent, timestampMs, targetUidProcState);
if (targetUidProcState <= mAppStandby.getBroadcastResponseFgThresholdState()) {
- // No need to track the broadcast response state while the target app is
+ // No need to track the broadcast response stats while the target app is
// in the foreground.
return;
}
+ if (doesPackageHoldExemptedRole(targetPackage, targetUser)) {
+ // Package holds an exempted role, so no need to track the broadcast response stats.
+ return;
+ }
+ if (doesPackageHoldExemptedPermission(targetPackage, targetUser)) {
+ // Package holds an exempted permission, so no need to track the broadcast response
+ // stats
+ return;
+ }
synchronized (mLock) {
final ArraySet<BroadcastEvent> broadcastEvents =
getOrCreateBroadcastEventsLocked(targetPackage, targetUser);
@@ -253,6 +289,62 @@
}
}
+ boolean doesPackageHoldExemptedRole(@NonNull String packageName, @NonNull UserHandle user) {
+ final List<String> exemptedRoles = mAppStandby.getBroadcastResponseExemptedRoles();
+ synchronized (mLock) {
+ for (int i = exemptedRoles.size() - 1; i >= 0; --i) {
+ final String roleName = exemptedRoles.get(i);
+ final List<String> roleHolders = getRoleHoldersLocked(roleName, user);
+ if (CollectionUtils.contains(roleHolders, packageName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean doesPackageHoldExemptedPermission(@NonNull String packageName,
+ @NonNull UserHandle user) {
+ final List<String> exemptedPermissions = mAppStandby
+ .getBroadcastResponseExemptedPermissions();
+ for (int i = exemptedPermissions.size() - 1; i >= 0; --i) {
+ final String permissionName = exemptedPermissions.get(i);
+ if (PermissionManager.checkPackageNamePermission(permissionName, packageName,
+ user.getIdentifier()) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ private List<String> getRoleHoldersLocked(@NonNull String roleName, @NonNull UserHandle user) {
+ ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.get(
+ user.getIdentifier());
+ if (roleHoldersForUser == null) {
+ roleHoldersForUser = new ArrayMap<>();
+ mExemptedRoleHoldersCache.put(user.getIdentifier(), roleHoldersForUser);
+ }
+ List<String> roleHolders = roleHoldersForUser.get(roleName);
+ if (roleHolders == null && mRoleManager != null) {
+ roleHolders = mRoleManager.getRoleHoldersAsUser(roleName, user);
+ roleHoldersForUser.put(roleName, roleHolders);
+ }
+ return roleHolders;
+ }
+
+ private void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+ synchronized (mLock) {
+ final ArrayMap<String, List<String>> roleHoldersForUser =
+ mExemptedRoleHoldersCache.get(user.getIdentifier());
+ if (roleHoldersForUser == null) {
+ return;
+ }
+ roleHoldersForUser.remove(roleName);
+ }
+ }
+
void onUserRemoved(@UserIdInt int userId) {
synchronized (mLock) {
mUserBroadcastEvents.remove(userId);
@@ -260,6 +352,7 @@
for (int i = mUserResponseStats.size() - 1; i >= 0; --i) {
mUserResponseStats.valueAt(i).remove(userId);
}
+ mExemptedRoleHoldersCache.remove(userId);
}
}
@@ -373,6 +466,8 @@
ipw.println();
dumpResponseStatsLocked(ipw);
ipw.println();
+ dumpRoleHoldersLocked(ipw);
+ ipw.println();
mLogger.dumpLogs(ipw);
}
@@ -417,5 +512,32 @@
}
ipw.decreaseIndent();
}
+
+ @GuardedBy("mLock")
+ private void dumpRoleHoldersLocked(@NonNull IndentingPrintWriter ipw) {
+ ipw.println("Role holders:");
+ ipw.increaseIndent();
+ for (int userIdx = 0; userIdx < mExemptedRoleHoldersCache.size(); ++userIdx) {
+ final int userId = mExemptedRoleHoldersCache.keyAt(userIdx);
+ final ArrayMap<String, List<String>> roleHoldersForUser =
+ mExemptedRoleHoldersCache.valueAt(userIdx);
+ ipw.println("User " + userId + ":");
+ ipw.increaseIndent();
+ for (int roleIdx = 0; roleIdx < roleHoldersForUser.size(); ++roleIdx) {
+ final String roleName = roleHoldersForUser.keyAt(roleIdx);
+ final List<String> holders = roleHoldersForUser.valueAt(roleIdx);
+ ipw.print(roleName + ": ");
+ for (int holderIdx = 0; holderIdx < holders.size(); ++holderIdx) {
+ if (holderIdx > 0) {
+ ipw.print(", ");
+ }
+ ipw.print(holders.get(holderIdx));
+ }
+ ipw.println();
+ }
+ ipw.decreaseIndent();
+ }
+ ipw.decreaseIndent();
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 078177b..ef13cd9 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -357,6 +357,7 @@
getDpmInternal();
// initialize mShortcutServiceInternal
getShortcutServiceInternal();
+ mResponseStatsTracker.onSystemServicesReady(getContext());
if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) {
try {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 0558648..39a6868 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -70,6 +70,7 @@
import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.wm.ActivityAssistInfo;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -86,10 +87,14 @@
final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";
+ /** The delay time for retrying to request DirectActions. */
+ private static final long REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS = 200;
+
final boolean mValid;
final Context mContext;
final Handler mHandler;
+ final Handler mDirectActionsHandler;
final VoiceInteractionManagerService.VoiceInteractionManagerServiceStub mServiceStub;
final int mUser;
final ComponentName mComponent;
@@ -184,6 +189,7 @@
int userHandle, ComponentName service) {
mContext = context;
mHandler = handler;
+ mDirectActionsHandler = new Handler(true);
mServiceStub = stub;
mUser = userHandle;
mComponent = service;
@@ -343,7 +349,10 @@
.getAttachedNonFinishingActivityForTask(taskId, null);
if (tokens == null || tokens.getAssistToken() != assistToken) {
Slog.w(TAG, "Unknown activity to query for direct actions");
- callback.sendResult(null);
+ mDirectActionsHandler.sendMessageDelayed(PooledLambda.obtainMessage(
+ VoiceInteractionManagerServiceImpl::retryRequestDirectActions,
+ VoiceInteractionManagerServiceImpl.this, token, taskId, assistToken,
+ cancellationCallback, callback), REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS);
} else {
try {
tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
@@ -355,6 +364,33 @@
}
}
+ private void retryRequestDirectActions(@NonNull IBinder token, int taskId,
+ @NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback,
+ @NonNull RemoteCallback callback) {
+ synchronized (mServiceStub) {
+ if (mActiveSession == null || token != mActiveSession.mToken) {
+ Slog.w(TAG, "retryRequestDirectActions does not match active session");
+ callback.sendResult(null);
+ return;
+ }
+ final ActivityTokens tokens = LocalServices.getService(
+ ActivityTaskManagerInternal.class)
+ .getAttachedNonFinishingActivityForTask(taskId, null);
+ if (tokens == null || tokens.getAssistToken() != assistToken) {
+ Slog.w(TAG, "Unknown activity to query for direct actions during retrying");
+ callback.sendResult(null);
+ } else {
+ try {
+ tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
+ mActiveSession.mInteractor, cancellationCallback, callback);
+ } catch (RemoteException e) {
+ Slog.w("Unexpected remote error", e);
+ callback.sendResult(null);
+ }
+ }
+ }
+ }
+
void performDirectActionLocked(@NonNull IBinder token, @NonNull String actionId,
@Nullable Bundle arguments, int taskId, IBinder assistToken,
@Nullable RemoteCallback cancellationCallback,