diff options
358 files changed, 4504 insertions, 3650 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 546efaad85ac..d19ecd450f0a 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5863,16 +5863,16 @@ public final class ActivityThread extends ClientTransactionHandler final boolean movedToDifferentDisplay = isDifferentDisplay(activity.getDisplayId(), displayId); - final Configuration currentResConfig = activity.getResources().getConfiguration(); - final int diff = currentResConfig.diffPublicOnly(newConfig); - final boolean hasPublicResConfigChange = diff != 0; + final Configuration currentConfig = activity.mCurrentConfig; + final int diff = currentConfig.diffPublicOnly(newConfig); + final boolean hasPublicConfigChange = diff != 0; final ActivityClientRecord r = getActivityClient(activityToken); // TODO(b/173090263): Use diff instead after the improvement of AssetManager and // ResourcesImpl constructions. - final boolean shouldUpdateResources = hasPublicResConfigChange - || shouldUpdateResources(activityToken, currentResConfig, newConfig, - amOverrideConfig, movedToDifferentDisplay, hasPublicResConfigChange); - final boolean shouldReportChange = shouldReportChange(activity.mCurrentConfig, newConfig, + final boolean shouldUpdateResources = hasPublicConfigChange + || shouldUpdateResources(activityToken, currentConfig, newConfig, amOverrideConfig, + movedToDifferentDisplay, hasPublicConfigChange); + final boolean shouldReportChange = shouldReportChange(diff, currentConfig, newConfig, r != null ? r.mSizeConfigurations : null, activity.mActivityInfo.getRealConfigChanged()); // Nothing significant, don't proceed with updating and reporting. @@ -5896,6 +5896,9 @@ public final class ActivityThread extends ClientTransactionHandler amOverrideConfig, contextThemeWrapperOverrideConfig); mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, displayId); + activity.mConfigChangeFlags = 0; + activity.mCurrentConfig = new Configuration(newConfig); + // Apply the ContextThemeWrapper override if necessary. // NOTE: Make sure the configurations are not modified, as they are treated as immutable // in many places. @@ -5906,10 +5909,8 @@ public final class ActivityThread extends ClientTransactionHandler activity.dispatchMovedToDisplay(displayId, configToReport); } - activity.mConfigChangeFlags = 0; if (shouldReportChange) { activity.mCalled = false; - activity.mCurrentConfig = new Configuration(newConfig); activity.onConfigurationChanged(configToReport); if (!activity.mCalled) { throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + @@ -5924,6 +5925,8 @@ public final class ActivityThread extends ClientTransactionHandler * Returns {@code true} if {@link Activity#onConfigurationChanged(Configuration)} should be * dispatched. * + * @param publicDiff Usually computed by {@link Configuration#diffPublicOnly(Configuration)}. + * This parameter is to prevent we compute it again. * @param currentConfig The current configuration cached in {@link Activity#mCurrentConfig}. * It is {@code null} before the first config update from the server side. * @param newConfig The updated {@link Configuration} @@ -5932,10 +5935,9 @@ public final class ActivityThread extends ClientTransactionHandler * @return {@code true} if the config change should be reported to the Activity */ @VisibleForTesting - public static boolean shouldReportChange(@Nullable Configuration currentConfig, + public static boolean shouldReportChange(int publicDiff, @Nullable Configuration currentConfig, @NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets sizeBuckets, int handledConfigChanges) { - final int publicDiff = currentConfig.diffPublicOnly(newConfig); // Don't report the change if there's no public diff between current and new config. if (publicDiff == 0) { return false; diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index fe75dd302beb..dc6825c85705 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -263,9 +263,12 @@ interface IActivityTaskManager { * @param taskId the id of the task to retrieve the sAutoapshots for * @param isLowResolution if set, if the snapshot needs to be loaded from disk, this will load * a reduced resolution of it, which is much faster + * @param takeSnapshotIfNeeded if set, call {@link #takeTaskSnapshot} to trigger the snapshot + if no cache exists. * @return a graphic buffer representing a screenshot of a task */ - android.window.TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution); + android.window.TaskSnapshot getTaskSnapshot( + int taskId, boolean isLowResolution, boolean takeSnapshotIfNeeded); /** * @param taskId the id of the task to take a snapshot of diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 20a4fdf658c6..10d6f2d6d04b 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -542,14 +542,17 @@ public class ApkLiteParseUtils { int minVer = DEFAULT_MIN_SDK_VERSION; String minCode = null; + boolean minAssigned = false; int targetVer = DEFAULT_TARGET_SDK_VERSION; String targetCode = null; if (!TextUtils.isEmpty(minSdkVersionString)) { try { minVer = Integer.parseInt(minSdkVersionString); + minAssigned = true; } catch (NumberFormatException ignored) { minCode = minSdkVersionString; + minAssigned = !TextUtils.isEmpty(minCode); } } @@ -558,7 +561,7 @@ public class ApkLiteParseUtils { targetVer = Integer.parseInt(targetSdkVersionString); } catch (NumberFormatException ignored) { targetCode = targetSdkVersionString; - if (minCode == null) { + if (!minAssigned) { minCode = targetCode; } } diff --git a/core/java/android/debug/AdbManagerInternal.java b/core/java/android/debug/AdbManagerInternal.java index d730129507d7..e448706fabfe 100644 --- a/core/java/android/debug/AdbManagerInternal.java +++ b/core/java/android/debug/AdbManagerInternal.java @@ -55,6 +55,12 @@ public abstract class AdbManagerInternal { public abstract File getAdbTempKeysFile(); /** + * Notify the AdbManager that the key files have changed and any in-memory state should be + * reloaded. + */ + public abstract void notifyKeyFilesUpdated(); + + /** * Starts adbd for a transport. */ public abstract void startAdbdForTransport(byte transportType); diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java index 3a042a5dee4d..e8e4fc988937 100644 --- a/core/java/android/hardware/radio/ProgramList.java +++ b/core/java/android/hardware/radio/ProgramList.java @@ -26,7 +26,6 @@ import android.os.Parcelable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -173,38 +172,63 @@ public final class ProgramList implements AutoCloseable { } } - void apply(@NonNull Chunk chunk) { + void apply(Chunk chunk) { + List<ProgramSelector.Identifier> removedList = new ArrayList<>(); + List<ProgramSelector.Identifier> changedList = new ArrayList<>(); + List<ProgramList.ListCallback> listCallbacksCopied; + List<OnCompleteListener> onCompleteListenersCopied = new ArrayList<>(); synchronized (mLock) { if (mIsClosed) return; mIsComplete = false; + listCallbacksCopied = new ArrayList<>(mListCallbacks); if (chunk.isPurge()) { - new HashSet<>(mPrograms.keySet()).stream().forEach(id -> removeLocked(id)); + for (ProgramSelector.Identifier id : mPrograms.keySet()) { + removeLocked(id, removedList); + } } - chunk.getRemoved().stream().forEach(id -> removeLocked(id)); - chunk.getModified().stream().forEach(info -> putLocked(info)); + chunk.getRemoved().stream().forEach(id -> removeLocked(id, removedList)); + chunk.getModified().stream().forEach(info -> putLocked(info, changedList)); if (chunk.isComplete()) { mIsComplete = true; - mOnCompleteListeners.forEach(cb -> cb.onComplete()); + onCompleteListenersCopied = new ArrayList<>(mOnCompleteListeners); + } + } + + for (int i = 0; i < removedList.size(); i++) { + for (int cbIndex = 0; cbIndex < listCallbacksCopied.size(); cbIndex++) { + listCallbacksCopied.get(cbIndex).onItemRemoved(removedList.get(i)); + } + } + for (int i = 0; i < changedList.size(); i++) { + for (int cbIndex = 0; cbIndex < listCallbacksCopied.size(); cbIndex++) { + listCallbacksCopied.get(cbIndex).onItemChanged(changedList.get(i)); + } + } + if (chunk.isComplete()) { + for (int cbIndex = 0; cbIndex < onCompleteListenersCopied.size(); cbIndex++) { + onCompleteListenersCopied.get(cbIndex).onComplete(); } } } - private void putLocked(@NonNull RadioManager.ProgramInfo value) { + private void putLocked(RadioManager.ProgramInfo value, + List<ProgramSelector.Identifier> changedIdentifierList) { ProgramSelector.Identifier key = value.getSelector().getPrimaryId(); mPrograms.put(Objects.requireNonNull(key), value); ProgramSelector.Identifier sel = value.getSelector().getPrimaryId(); - mListCallbacks.forEach(cb -> cb.onItemChanged(sel)); + changedIdentifierList.add(sel); } - private void removeLocked(@NonNull ProgramSelector.Identifier key) { + private void removeLocked(ProgramSelector.Identifier key, + List<ProgramSelector.Identifier> removedIdentifierList) { RadioManager.ProgramInfo removed = mPrograms.remove(Objects.requireNonNull(key)); if (removed == null) return; ProgramSelector.Identifier sel = removed.getSelector().getPrimaryId(); - mListCallbacks.forEach(cb -> cb.onItemRemoved(sel)); + removedIdentifierList.add(sel); } /** diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING index 22ddbccbaaae..c70f1f07e739 100644 --- a/core/java/android/os/TEST_MAPPING +++ b/core/java/android/os/TEST_MAPPING @@ -59,6 +59,18 @@ }, { "file_patterns": [ + "Parcel\\.java", + "[^/]*Bundle[^/]*\\.java" + ], + "name": "FrameworksMockingCoreTests", + "options": [ + { "include-filter": "android.os.BundleRecyclingTest"}, + { "exclude-annotation": "androidx.test.filters.FlakyTest" }, + { "exclude-annotation": "org.junit.Ignore" } + ] + }, + { + "file_patterns": [ "BatteryUsageStats[^/]*\\.java", "PowerComponents\\.java", "[^/]*BatteryConsumer[^/]*\\.java" diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl index 1f64fb8ca2ec..1981c9d66c8b 100644 --- a/core/java/android/view/IRemoteAnimationRunner.aidl +++ b/core/java/android/view/IRemoteAnimationRunner.aidl @@ -46,5 +46,5 @@ oneway interface IRemoteAnimationRunner { * won't have any effect anymore. */ @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) - void onAnimationCancelled(); + void onAnimationCancelled(boolean isKeyguardOccluded); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 64151d9d6c3f..3811d032a384 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -604,6 +604,8 @@ public final class ViewRootImpl implements ViewParent, */ private boolean mCheckIfCanDraw = false; + private boolean mDrewOnceForSync = false; + int mSyncSeqId = 0; int mLastSyncSeqId = 0; @@ -2816,10 +2818,6 @@ public final class ViewRootImpl implements ViewParent, // Execute enqueued actions on every traversal in case a detached view enqueued an action getRunQueue().executeActions(mAttachInfo.mHandler); - if (mApplyInsetsRequested) { - dispatchApplyInsets(host); - } - if (mFirst) { // make sure touch mode code executes by setting cached value // to opposite of the added touch mode. @@ -2883,6 +2881,18 @@ public final class ViewRootImpl implements ViewParent, } } + if (mApplyInsetsRequested) { + dispatchApplyInsets(host); + if (mLayoutRequested) { + // Short-circuit catching a new layout request here, so + // we don't need to go through two layout passes when things + // change due to fitting system windows, which can happen a lot. + windowSizeMayChange |= measureHierarchy(host, lp, + mView.getContext().getResources(), + desiredWindowWidth, desiredWindowHeight); + } + } + if (layoutRequested) { // Clear this now, so that if anything requests a layout in the // rest of this function we will catch it and re-run a full @@ -2991,6 +3001,9 @@ public final class ViewRootImpl implements ViewParent, reportNextDraw(); mSyncBuffer = true; isSyncRequest = true; + if (!cancelDraw) { + mDrewOnceForSync = false; + } } final boolean surfaceControlChanged = @@ -3512,9 +3525,11 @@ public final class ViewRootImpl implements ViewParent, mCheckIfCanDraw = isSyncRequest || cancelDraw; - boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || cancelDraw; + boolean cancelAndRedraw = + mAttachInfo.mTreeObserver.dispatchOnPreDraw() || (cancelDraw && mDrewOnceForSync); if (!cancelAndRedraw) { createSyncIfNeeded(); + mDrewOnceForSync = true; } if (!isViewVisible) { diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 52fd7fec932e..22340c6b0c55 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -75,6 +75,8 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH; @@ -206,6 +208,8 @@ public class InteractionJankMonitor { public static final int CUJ_SETTINGS_TOGGLE = 57; public static final int CUJ_SHADE_DIALOG_OPEN = 58; public static final int CUJ_USER_DIALOG_OPEN = 59; + public static final int CUJ_TASKBAR_EXPAND = 60; + public static final int CUJ_TASKBAR_COLLAPSE = 61; private static final int NO_STATSD_LOGGING = -1; @@ -274,6 +278,8 @@ public class InteractionJankMonitor { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_TOGGLE, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE, }; private static volatile InteractionJankMonitor sInstance; @@ -354,6 +360,8 @@ public class InteractionJankMonitor { CUJ_SETTINGS_TOGGLE, CUJ_SHADE_DIALOG_OPEN, CUJ_USER_DIALOG_OPEN, + CUJ_TASKBAR_EXPAND, + CUJ_TASKBAR_COLLAPSE }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -792,6 +800,10 @@ public class InteractionJankMonitor { return "SHADE_DIALOG_OPEN"; case CUJ_USER_DIALOG_OPEN: return "USER_DIALOG_OPEN"; + case CUJ_TASKBAR_EXPAND: + return "TASKBAR_EXPAND"; + case CUJ_TASKBAR_COLLAPSE: + return "TASKBAR_COLLAPSE"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index e93a7854f1cd..65bec0e405ea 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -33,6 +33,7 @@ import android.view.InsetsVisibilities; import com.android.internal.statusbar.IAddTileResultCallback; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.view.AppearanceRegion; @@ -202,10 +203,12 @@ oneway interface IStatusBar * @param behavior the behavior of the focused window. * @param requestedVisibilities the collection of the requested visibilities of system insets. * @param packageName the package name of the focused app. + * @param letterboxDetails a set of letterbox details of apps visible on the screen. */ void onSystemBarAttributesChanged(int displayId, int appearance, in AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - int behavior, in InsetsVisibilities requestedVisibilities, String packageName); + int behavior, in InsetsVisibilities requestedVisibilities, String packageName, + in LetterboxDetails[] letterboxDetails); /** * Notifies System UI to show transient bars. The transient bars are system bars, e.g., status diff --git a/core/java/com/android/internal/statusbar/LetterboxDetails.aidl b/core/java/com/android/internal/statusbar/LetterboxDetails.aidl new file mode 100644 index 000000000000..7875796cd3ba --- /dev/null +++ b/core/java/com/android/internal/statusbar/LetterboxDetails.aidl @@ -0,0 +1,19 @@ +/* + * 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.internal.statusbar; + +parcelable LetterboxDetails; diff --git a/core/java/com/android/internal/statusbar/LetterboxDetails.java b/core/java/com/android/internal/statusbar/LetterboxDetails.java new file mode 100644 index 000000000000..5d14ee347482 --- /dev/null +++ b/core/java/com/android/internal/statusbar/LetterboxDetails.java @@ -0,0 +1,243 @@ +/* + * 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.internal.statusbar; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.InsetsFlags; +import android.view.ViewDebug; +import android.view.WindowInsetsController.Appearance; + +import com.android.internal.util.DataClass; + +/** + * Details about the letterbox state of an app. + */ +@DataClass( + genParcelable = true, + genAidl = true, + genToString = true, + genGetters = false, + genEqualsHashCode = true +) +public class LetterboxDetails implements Parcelable { + + @NonNull + private final Rect mLetterboxInnerBounds; + @NonNull + private final Rect mLetterboxFullBounds; + private final int mAppAppearance; + + /** + * Returns the bounds of the inner letterbox (app content). + * + * <p>When an app is letterboxed, it is not using the full bounds of its window. Here we return + * the bounds that are being used for the app content. + * + * <pre> + * +-------+---------+-------+ + * | | | | + * | | | | + * | Outer | Inner | Outer | + * | | | | + * | | | | + * +-------+-------- +-------+ + * <pre> + */ + @NonNull + public Rect getLetterboxInnerBounds() { + return mLetterboxInnerBounds; + } + + /** + * Returns the full bounds of the letterbox. + * + * <p>These are the entire bounds of the window where the app is placed. We cannot assume that + * the full bounds are the bounds of the screen, as the app can be in split-screen, or can have + * some margin due to display cutouts. + * + * <pre> + * ---- Full bounds width ---- + * +-------+---------+-------+ | + * | | | | | + * | | | | | + * | Outer | Inner | Outer | + Full bounds height + * | | | | | + * | | | | | + * +-------+-------- +-------+ | + * </pre> + */ + @NonNull + public Rect getLetterboxFullBounds() { + return mLetterboxFullBounds; + } + + /** + * Returns the {@link Appearance} of the inner letterbox (app content). + */ + @Appearance + public int getAppAppearance() { + return mAppAppearance; + } + + /** Returns a string representation of the {@link #getAppAppearance()} property. */ + public String appAppearanceToString() { + return ViewDebug.flagsToString(InsetsFlags.class, "appearance", mAppAppearance); + } + + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/statusbar/LetterboxDetails.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @DataClass.Generated.Member + public LetterboxDetails( + @NonNull Rect letterboxInnerBounds, + @NonNull Rect letterboxFullBounds, + int appAppearance) { + this.mLetterboxInnerBounds = letterboxInnerBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxInnerBounds); + this.mLetterboxFullBounds = letterboxFullBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxFullBounds); + this.mAppAppearance = appAppearance; + + // onConstructed(); // You can define this method to get a callback + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "LetterboxDetails { " + + "letterboxInnerBounds = " + mLetterboxInnerBounds + ", " + + "letterboxFullBounds = " + mLetterboxFullBounds + ", " + + "appAppearance = " + appAppearanceToString() + + " }"; + } + + @Override + @DataClass.Generated.Member + public boolean equals(@Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(LetterboxDetails other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + LetterboxDetails that = (LetterboxDetails) o; + //noinspection PointlessBooleanExpression + return true + && java.util.Objects.equals(mLetterboxInnerBounds, that.mLetterboxInnerBounds) + && java.util.Objects.equals(mLetterboxFullBounds, that.mLetterboxFullBounds) + && mAppAppearance == that.mAppAppearance; + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + java.util.Objects.hashCode(mLetterboxInnerBounds); + _hash = 31 * _hash + java.util.Objects.hashCode(mLetterboxFullBounds); + _hash = 31 * _hash + mAppAppearance; + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeTypedObject(mLetterboxInnerBounds, flags); + dest.writeTypedObject(mLetterboxFullBounds, flags); + dest.writeInt(mAppAppearance); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + protected LetterboxDetails(@NonNull Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + Rect letterboxInnerBounds = (Rect) in.readTypedObject(Rect.CREATOR); + Rect letterboxFullBounds = (Rect) in.readTypedObject(Rect.CREATOR); + int appAppearance = in.readInt(); + + this.mLetterboxInnerBounds = letterboxInnerBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxInnerBounds); + this.mLetterboxFullBounds = letterboxFullBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxFullBounds); + this.mAppAppearance = appAppearance; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<LetterboxDetails> CREATOR + = new Parcelable.Creator<LetterboxDetails>() { + @Override + public LetterboxDetails[] newArray(int size) { + return new LetterboxDetails[size]; + } + + @Override + public LetterboxDetails createFromParcel(@NonNull Parcel in) { + return new LetterboxDetails(in); + } + }; + + @DataClass.Generated( + time = 1656941109526L, + codegenVersion = "1.0.23", + sourceFile = "frameworks/base/core/java/com/android/internal/statusbar/LetterboxDetails.java", + inputSignatures = "private final @android.annotation.NonNull android.graphics.Rect mLetterboxInnerBounds\nprivate final @android.annotation.NonNull android.graphics.Rect mLetterboxFullBounds\nprivate final int mAppAppearance\npublic @android.annotation.NonNull android.graphics.Rect getLetterboxInnerBounds()\npublic @android.annotation.NonNull android.graphics.Rect getLetterboxFullBounds()\npublic @android.view.WindowInsetsController.Appearance int getAppAppearance()\npublic java.lang.String appAppearanceToString()\nclass LetterboxDetails extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genToString=true, genGetters=false, genEqualsHashCode=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java index 4dcc82e2e572..8b898f01554f 100644 --- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -43,12 +43,14 @@ public final class RegisterStatusBarResult implements Parcelable { public final InsetsVisibilities mRequestedVisibilities; public final String mPackageName; public final int[] mTransientBarTypes; + public final LetterboxDetails[] mLetterboxDetails; public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1, int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis, int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken, boolean navbarColorManagedByIme, int behavior, InsetsVisibilities requestedVisibilities, - String packageName, @NonNull int[] transientBarTypes) { + String packageName, @NonNull int[] transientBarTypes, + LetterboxDetails[] letterboxDetails) { mIcons = new ArrayMap<>(icons); mDisabledFlags1 = disabledFlags1; mAppearance = appearance; @@ -63,6 +65,7 @@ public final class RegisterStatusBarResult implements Parcelable { mRequestedVisibilities = requestedVisibilities; mPackageName = packageName; mTransientBarTypes = transientBarTypes; + mLetterboxDetails = letterboxDetails; } @Override @@ -86,6 +89,7 @@ public final class RegisterStatusBarResult implements Parcelable { dest.writeTypedObject(mRequestedVisibilities, 0); dest.writeString(mPackageName); dest.writeIntArray(mTransientBarTypes); + dest.writeParcelableArray(mLetterboxDetails, flags); } /** @@ -112,10 +116,13 @@ public final class RegisterStatusBarResult implements Parcelable { source.readTypedObject(InsetsVisibilities.CREATOR); final String packageName = source.readString(); final int[] transientBarTypes = source.createIntArray(); + final LetterboxDetails[] letterboxDetails = + source.readParcelableArray(null, LetterboxDetails.class); return new RegisterStatusBarResult(icons, disabledFlags1, appearance, appearanceRegions, imeWindowVis, imeBackDisposition, showImeSwitcher, disabledFlags2, imeToken, navbarColorManagedByIme, behavior, - requestedVisibilities, packageName, transientBarTypes); + requestedVisibilities, packageName, transientBarTypes, + letterboxDetails); } @Override diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 7b97084883d4..6ebc5297ebc1 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -628,7 +628,7 @@ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهرهتان ضربه بزنید، سپس چهرهتان را دوباره اضافه کنید"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"راهاندازی «قفلگشایی با چهره»"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"برای باز کردن قفل تلفن خود به آن نگاه کنید"</string> - <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"برای استفاده از «قفلگشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات > حریمخصوصی» روشن کنید"</string> + <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"برای استفاده از «قفلگشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات > حریم خصوصی» روشن کنید"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"راهاندازی روشهای بیشتر برای باز کردن قفل"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"برای افزودن اثر انگشت، ضربه بزنید"</string> <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفلگشایی با اثر انگشت"</string> @@ -1051,7 +1051,7 @@ <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string> <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"به برنامه اجازه میدهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامههای مخرب میتوانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایتهای وب کتابخانه بفرستند."</string> <string name="save_password_message" msgid="2146409467245462965">"میخواهید مرورگر این گذرواژه را به خاطر داشته باشد؟"</string> - <string name="save_password_notnow" msgid="2878327088951240061">"اکنون نه"</string> + <string name="save_password_notnow" msgid="2878327088951240061">"حالا نه"</string> <string name="save_password_remember" msgid="6490888932657708341">"به خاطر سپردن"</string> <string name="save_password_never" msgid="6776808375903410659">"هیچوقت"</string> <string name="open_permission_deny" msgid="5136793905306987251">"شما اجازه بازکردن این صفحه را ندارید."</string> @@ -2271,7 +2271,7 @@ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"لغو انسداد دوربین دستگاه"</string> <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"برای <b><xliff:g id="APP">%s</xliff:g></b> و همه برنامهها و سرویسها"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"لغو انسداد"</string> - <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریمخصوصی حسگر"</string> + <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریم خصوصی حسگر"</string> <string name="splash_screen_view_icon_description" msgid="180638751260598187">"نماد برنامه"</string> <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"تصویر نمانامسازی برنامه"</string> <string name="view_and_control_notification_title" msgid="4300765399209912240">"بررسی تنظیمات دسترسی"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index c966b958e4b8..c0fae1bc7160 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -269,7 +269,7 @@ <string name="global_action_lockdown" msgid="2475471405907902963">"Құлыптау"</string> <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string> <string name="notification_hidden_text" msgid="2835519769868187223">"Жаңа хабарландыру"</string> - <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалды пернетақта"</string> + <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалдық пернетақта"</string> <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физикалық пернетақта"</string> <string name="notification_channel_security" msgid="8516754650348238057">"Қауіпсіздік"</string> <string name="notification_channel_car_mode" msgid="2123919247040988436">"Көлік режимі"</string> @@ -1139,7 +1139,7 @@ <string name="replace" msgid="7842675434546657444">"… сөзін алмастыру"</string> <string name="delete" msgid="1514113991712129054">"Жою"</string> <string name="copyUrl" msgid="6229645005987260230">"URL мекенжайын көшіру"</string> - <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді бөлектеу"</string> + <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді ерекшелеу"</string> <string name="undo" msgid="3175318090002654673">"Қайтару"</string> <string name="redo" msgid="7231448494008532233">"Қайтару"</string> <string name="autofill" msgid="511224882647795296">"Aвтотолтыру"</string> @@ -1384,7 +1384,7 @@ <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ҚАБЫЛДАМАУ"</string> <string name="select_input_method" msgid="3971267998568587025">"Енгізу әдісін таңдау"</string> <string name="show_ime" msgid="6406112007347443383">"Физикалық пернетақта қосулы кезде оны экранға шығару"</string> - <string name="hardware" msgid="1800597768237606953">"Виртуалды пернетақтаны көрсету"</string> + <string name="hardware" msgid="1800597768237606953">"Виртуалдық пернетақтаны көрсету"</string> <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Физикалық пернетақтаны конфигурациялау"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -1483,7 +1483,7 @@ <string name="wallpaper_binding_label" msgid="1197440498000786738">"Артқы фоны"</string> <string name="chooser_wallpaper" msgid="3082405680079923708">"Артқы фонын өзгерту"</string> <string name="notification_listener_binding_label" msgid="2702165274471499713">"Хабар бақылағыш"</string> - <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалды шынайылық тыңдаушысы"</string> + <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалдық шынайылық тыңдаушысы"</string> <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Шарт провайдері"</string> <string name="notification_ranker_binding_label" msgid="432708245635563763">"Хабарландыруларды жіктеу қызметі"</string> <string name="vpn_title" msgid="5906991595291514182">"VPN белсенді"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index d8a389455c4b..57672a245f9d 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1234,7 +1234,7 @@ <string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string> <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон жаңырууда…"</string> <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Планшет жаңыртылууда…"</string> - <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңыртылууда…"</string> + <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңырууда…"</string> <string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон күйгүзүлүүдө…"</string> <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android жүргүзүлүүдө…"</string> <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет күйгүзүлүүдө…"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 1b154004fa00..fd9bfc61dc11 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -48,7 +48,7 @@ <string name="invalidPin" msgid="7542498253319440408">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു പിൻ ടൈപ്പുചെയ്യുക."</string> <string name="invalidPuk" msgid="8831151490931907083">"എട്ടോ അതിലധികമോ അക്കങ്ങളുള്ള ഒരു PUK ടൈപ്പുചെയ്യുക."</string> <string name="needPuk" msgid="7321876090152422918">"നിങ്ങളുടെ സിം കാർഡ് PUK ലോക്ക് ചെയ്തതാണ്. ഇത് അൺലോക്ക് ചെയ്യാൻ PUK കോഡ് ടൈപ്പുചെയ്യുക."</string> - <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് തടഞ്ഞത് മാറ്റാൻ PUK2 ടൈപ്പുചെയ്യുക."</string> + <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് അൺബ്ലോക്ക് ചെയ്യാൻ PUK2 ടൈപ്പ് ചെയ്യുക."</string> <string name="enablePin" msgid="2543771964137091212">"വിജയകരമല്ല, സിം/RUIM ലോക്ക് പ്രവർത്തനക്ഷമമാക്കുക."</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584"> <item quantity="other">SIM ലോക്കാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item> @@ -1018,7 +1018,7 @@ <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ഈ പേജിൽ തുടരുക"</string> <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nഈ പേജിൽ നിന്നും നാവിഗേറ്റുചെയ്തു പോകണമെന്ന് തീർച്ചയാണോ?"</string> <string name="save_password_label" msgid="9161712335355510035">"സ്ഥിരീകരിക്കുക"</string> - <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഇരട്ട-ടാപ്പുചെയ്യുക."</string> + <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഡബിൾ ടാപ്പ് ചെയ്യുക."</string> <string name="autofill_this_form" msgid="3187132440451621492">"ഓട്ടോഫിൽ"</string> <string name="setup_autofill" msgid="5431369130866618567">"ഓട്ടോഫിൽ സജ്ജീകരിക്കുക"</string> <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> ഉപയോഗിച്ച് സ്വമേധയാ പൂരിപ്പിക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 9f1453503e28..7293701c9bb2 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -289,9 +289,9 @@ <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Хандалтын ашиглалт"</string> - <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string> - <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string> - <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string> + <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батарей ашиглаж байна"</string> + <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батарей ашиглаж байна"</string> + <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string> <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string> <string name="safeMode" msgid="8974401416068943888">"Аюулгүй горим"</string> <string name="android_system_label" msgid="5974767339591067210">"Андройд систем"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index f53856697337..74bda7804c3e 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -698,7 +698,7 @@ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचण्याची अनुमती देते."</string> <string name="permlab_sdcardWrite" msgid="4863021819671416668">"तुमच्या शेअर केलेल्या स्टोरेजच्या आशयांमध्ये सुधारणा करा किंवा हटवा"</string> <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजचे आशय लिहिण्याची अनमती देते."</string> - <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/प्राप्त करा"</string> + <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/मिळवा"</string> <string name="permdesc_use_sip" msgid="3590270893253204451">"ॲपला SIP कॉल करण्याची आणि प्राप्त करण्याची अनुमती देते."</string> <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करा"</string> <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करण्यासाठी ॲपला अनुमती देते."</string> @@ -734,7 +734,7 @@ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string> <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM प्रमाणपत्रे अॅक्सेस करा"</string> <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य ॲप्सकरिता कधीही आवश्यकता नसते."</string> - <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string> + <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती मिळवा"</string> <string name="permdesc_handoverStatus" msgid="3842269451732571070">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string> <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM प्रमाणपत्रे काढा"</string> <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यकता नसते."</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index f63dfefde7f3..95cff2cb8939 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -93,7 +93,7 @@ <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status for mobildata"</string> <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-meldinger"</string> <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Talepostmeldinger"</string> - <string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi-anrop"</string> + <string name="notification_channel_wfc" msgid="9048240466765169038">"Wifi-anrop"</string> <string name="notification_channel_sim" msgid="5098802350325677490">"SIM-status"</string> <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"SIM-status er satt til høy prioritet"</string> <string name="peerTtyModeFull" msgid="337553730440832160">"Motpart ba om TTY-modus FULL"</string> @@ -122,25 +122,25 @@ <string name="roamingText11" msgid="5245687407203281407">"Roaming-banner på"</string> <string name="roamingText12" msgid="673537506362152640">"Roaming-banner av"</string> <string name="roamingTextSearching" msgid="5323235489657753486">"Leter etter tjeneste"</string> - <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere Wi-Fi-anrop"</string> + <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere wifi-anrop"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> + <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på wifi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> - <item msgid="4795145070505729156">"Problem med å registrere Wi-Fi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item> + <item msgid="4795145070505729156">"Problem med å registrere wifi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item> </string-array> <!-- no translation found for wfcSpnFormat_spn (2982505428519096311) --> <skip /> - <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string> - <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-anrop"</string> + <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wifi-anrop"</string> + <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wifi-anrop"</string> <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN-anrop"</string> <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string> <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string> - <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wi-Fi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string> + <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wifi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string> <string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string> - <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wi-Fi-anrop"</string> + <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wifi-anrop"</string> <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string> - <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-anrop"</string> + <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wifi-anrop"</string> <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Av"</string> <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via Wi-Fi"</string> @@ -1041,9 +1041,9 @@ <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lese nettbokmerkene og nettloggen din"</string> <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Lar appen lese loggen for alle nettadressene nettleseren har besøkt, og alle bokmerkene i nettleseren. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"skrive nettbokmerker og nettlogg"</string> - <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> - <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> - <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> + <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> + <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> + <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string> <string name="permlab_setAlarm" msgid="1158001610254173567">"stille alarm"</string> <string name="permdesc_setAlarm" msgid="2185033720060109640">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string> <string name="permlab_addVoicemail" msgid="4770245808840814471">"legge til talepost"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 38d9d9aee8b8..64789fb32dcb 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -471,7 +471,7 @@ <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string> <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"మీ ప్రమేయం లేకుండా కాల్స్ చేయడం కోసం IMS సేవను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_readPhoneState" msgid="8138526903259297969">"ఫోన్ స్టేటస్ మరియు గుర్తింపుని చదవడం"</string> - <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్లను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్ను కనుగొనడానికి యాప్ను అనుమతిస్తుంది."</string> + <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్లను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ యాక్టివ్గా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్ను కనుగొనడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"ప్రాథమిక టెలిఫోన్ స్టేటస్, గుర్తింపును చదవండి"</string> <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"పరికరం తాలూకు ప్రాథమిక టెలిఫోన్ ఫీచర్లను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"కాల్స్ను సిస్టమ్ ద్వారా వెళ్లేలా చేయి"</string> @@ -1141,7 +1141,7 @@ <string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string> <string name="selectTextMode" msgid="3225108910999318778">"వచనాన్ని ఎంచుకోండి"</string> <string name="undo" msgid="3175318090002654673">"చర్య రద్దు చేయి"</string> - <string name="redo" msgid="7231448494008532233">"చర్యను పునరావృతం చేయి"</string> + <string name="redo" msgid="7231448494008532233">"చర్యను రిపీట్ చేయి"</string> <string name="autofill" msgid="511224882647795296">"ఆటోఫిల్"</string> <string name="textSelectionCABTitle" msgid="5151441579532476940">"వచన ఎంపిక"</string> <string name="addToDictionary" msgid="8041821113480950096">"నిఘంటువుకు జోడించు"</string> @@ -1334,7 +1334,7 @@ <string name="sim_added_title" msgid="7930779986759414595">"సిమ్ కార్డు జోడించబడింది"</string> <string name="sim_added_message" msgid="6602906609509958680">"మొబైల్ నెట్వర్క్ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string> <string name="sim_restart_button" msgid="8481803851341190038">"రీస్టార్ట్ చేయండి"</string> - <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను సక్రియం చేయండి"</string> + <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను యాక్టివేట్ చేయండి"</string> <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్ను డౌన్లోడ్ చేయండి"</string> <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ని డౌన్లోడ్ చేయండి"</string> <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"యాప్ని డౌన్లోడ్ చేయి"</string> @@ -1383,7 +1383,7 @@ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"షేర్ చేయి"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"తిరస్కరిస్తున్నాను"</string> <string name="select_input_method" msgid="3971267998568587025">"ఇన్పుట్ పద్ధతిని ఎంచుకోండి"</string> - <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string> + <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ యాక్టివ్గా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string> <string name="hardware" msgid="1800597768237606953">"వర్చువల్ కీబోర్డ్ను చూపు"</string> <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"భౌతిక కీబోర్డుని కాన్ఫిగర్ చేయండి"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాష మరియు లేఅవుట్ను ఎంచుకోవడానికి నొక్కండి"</string> @@ -1647,7 +1647,7 @@ <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"చెల్లని పిన్ కోడ్."</string> <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string> <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK కోడ్ 8 సంఖ్యలు ఉండాలి."</string> - <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string> + <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. రిపీట్ ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"పిన్ కోడ్లు సరిపోలలేదు"</string> <string name="kg_login_too_many_attempts" msgid="699292728290654121">"చాలా ఎక్కువ ఆకృతి ప్రయత్నాలు చేశారు"</string> <string name="kg_login_instructions" msgid="3619844310339066827">"అన్లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string> diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java index 0f05be06bff6..c53fb23ba948 100644 --- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java +++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java @@ -20,6 +20,7 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B import static com.google.common.truth.Truth.assertThat; +import android.graphics.Rect; import android.os.Binder; import android.os.Parcel; import android.os.UserHandle; @@ -48,7 +49,11 @@ public class RegisterStatusBarResultTest { final ArrayMap<String, StatusBarIcon> iconMap = new ArrayMap<>(); iconMap.put(dumyIconKey, new StatusBarIcon("com.android.internal.statusbar.test", UserHandle.of(100), 123, 1, 2, "dummyIconDescription")); - + final LetterboxDetails letterboxDetails = new LetterboxDetails( + /* letterboxInnerBounds= */ new Rect(1, 2, 3, 4), + /* letterboxFullBounds= */ new Rect(5, 6, 7, 8), + /* appAppearance= */ 321 + ); final RegisterStatusBarResult original = new RegisterStatusBarResult(iconMap, 0x2 /* disabledFlags1 */, 0x4 /* appearance */, @@ -62,7 +67,8 @@ public class RegisterStatusBarResultTest { BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, new InsetsVisibilities() /* requestedVisibilities */, "test" /* packageName */, - new int[0] /* transientBarTypes */); + new int[0] /* transientBarTypes */, + new LetterboxDetails[] {letterboxDetails}); final RegisterStatusBarResult copy = clone(original); @@ -84,6 +90,7 @@ public class RegisterStatusBarResultTest { assertThat(copy.mRequestedVisibilities).isEqualTo(original.mRequestedVisibilities); assertThat(copy.mPackageName).isEqualTo(original.mPackageName); assertThat(copy.mTransientBarTypes).isEqualTo(original.mTransientBarTypes); + assertThat(copy.mLetterboxDetails).isEqualTo(original.mLetterboxDetails); } private RegisterStatusBarResult clone(RegisterStatusBarResult original) { diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java index 47f70ddf2d42..8d3751e6ad6c 100644 --- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java +++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java @@ -207,8 +207,8 @@ public class ActivityThreadClientTest { final Configuration currentConfig = new Configuration(); assertFalse("Must not report change if no public diff", - shouldReportChange(currentConfig, newConfig, null /* sizeBuckets */, - 0 /* handledConfigChanges */)); + shouldReportChange(0 /* publicDiff */, currentConfig, newConfig, + null /* sizeBuckets */, 0 /* handledConfigChanges */)); final int[] verticalThresholds = {100, 400}; final SizeConfigurationBuckets buckets = new SizeConfigurationBuckets( @@ -221,25 +221,25 @@ public class ActivityThreadClientTest { newConfig.screenHeightDp = 300; assertFalse("Must not report changes if the diff is small and not handled", - shouldReportChange(currentConfig, newConfig, buckets, - CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, + newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); assertTrue("Must report changes if the small diff is handled", - shouldReportChange(currentConfig, newConfig, buckets, - CONFIG_SCREEN_SIZE /* handledConfigChanges */)); + shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, newConfig, + buckets, CONFIG_SCREEN_SIZE /* handledConfigChanges */)); currentConfig.fontScale = 0.8f; newConfig.fontScale = 1.2f; assertTrue("Must report handled changes regardless of small unhandled change", - shouldReportChange(currentConfig, newConfig, buckets, - CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */, + currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); newConfig.screenHeightDp = 500; assertFalse("Must not report changes if there's unhandled big changes", - shouldReportChange(currentConfig, newConfig, buckets, - CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */, + currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); } private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) { diff --git a/core/tests/mockingcoretests/src/android/os/BundleRecyclingTest.java b/core/tests/mockingcoretests/src/android/os/BundleRecyclingTest.java new file mode 100644 index 000000000000..7c7649813824 --- /dev/null +++ b/core/tests/mockingcoretests/src/android/os/BundleRecyclingTest.java @@ -0,0 +1,256 @@ +/* + * 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 android.os; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.dx.mockito.inline.extended.StaticMockitoSession; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.quality.Strictness; +import org.mockito.stubbing.Answer; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Test for verifying {@link android.os.Bundle} recycles the underlying parcel where needed. + * + * <p>Build/Install/Run: + * atest FrameworksMockingCoreTests:android.os.BundleRecyclingTest + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public class BundleRecyclingTest { + private Parcel mParcelSpy; + private Bundle mBundle; + + @Before + public void setUp() throws Exception { + setUpBundle(/* hasLazy */ true); + } + + @Test + public void bundleClear_whenUnparcelledWithoutLazy_recyclesParcelOnce() { + setUpBundle(/* hasLazy */ false); + // Will unparcel and immediately recycle parcel + assertNotNull(mBundle.getString("key")); + verify(mParcelSpy, times(1)).recycle(); + assertFalse(mBundle.isDefinitelyEmpty()); + + // Should not recycle again + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + assertTrue(mBundle.isDefinitelyEmpty()); + } + + @Test + public void bundleClear_whenParcelled_recyclesParcel() { + assertTrue(mBundle.isParcelled()); + verify(mParcelSpy, times(0)).recycle(); + + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + assertTrue(mBundle.isDefinitelyEmpty()); + + // Should not recycle again + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + } + + @Test + public void bundleClear_whenUnparcelledWithLazyValueUnwrapped_recyclesParcel() { + // Will unparcel with a lazy value, and immediately unwrap the lazy value, + // with no lazy values left at the end of getParcelable + assertNotNull(mBundle.getParcelable("key", CustomParcelable.class)); + verify(mParcelSpy, times(0)).recycle(); + + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + assertTrue(mBundle.isDefinitelyEmpty()); + + // Should not recycle again + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + } + + @Test + public void bundleClear_whenUnparcelledWithLazy_recyclesParcel() { + // Will unparcel but keep the CustomParcelable lazy + assertFalse(mBundle.isEmpty()); + verify(mParcelSpy, times(0)).recycle(); + + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + assertTrue(mBundle.isDefinitelyEmpty()); + + // Should not recycle again + mBundle.clear(); + verify(mParcelSpy, times(1)).recycle(); + } + + @Test + public void bundleClear_whenClearedWithSharedParcel_doesNotRecycleParcel() { + Bundle copy = new Bundle(); + copy.putAll(mBundle); + + mBundle.clear(); + assertTrue(mBundle.isDefinitelyEmpty()); + + copy.clear(); + assertTrue(copy.isDefinitelyEmpty()); + + verify(mParcelSpy, never()).recycle(); + } + + @Test + public void bundleClear_whenClearedWithCopiedParcel_doesNotRecycleParcel() { + // Will unparcel but keep the CustomParcelable lazy + assertFalse(mBundle.isEmpty()); + + Bundle copy = mBundle.deepCopy(); + copy.putAll(mBundle); + + mBundle.clear(); + assertTrue(mBundle.isDefinitelyEmpty()); + + copy.clear(); + assertTrue(copy.isDefinitelyEmpty()); + + verify(mParcelSpy, never()).recycle(); + } + + private void setUpBundle(boolean hasLazy) { + AtomicReference<Parcel> parcel = new AtomicReference<>(); + StaticMockitoSession session = mockitoSession() + .strictness(Strictness.STRICT_STUBS) + .spyStatic(Parcel.class) + .startMocking(); + doAnswer((Answer<Parcel>) invocationOnSpy -> { + Parcel spy = (Parcel) invocationOnSpy.callRealMethod(); + spyOn(spy); + parcel.set(spy); + return spy; + }).when(() -> Parcel.obtain()); + + Bundle bundle = new Bundle(); + bundle.setClassLoader(getClass().getClassLoader()); + Parcel p = createBundle(hasLazy); + bundle.readFromParcel(p); + p.recycle(); + + session.finishMocking(); + + mParcelSpy = parcel.get(); + mBundle = bundle; + } + + /** + * Create a test bundle, parcel it and return the parcel. + */ + private Parcel createBundle(boolean hasLazy) { + final Bundle source = new Bundle(); + if (hasLazy) { + source.putParcelable("key", new CustomParcelable(13, "Tiramisu")); + } else { + source.putString("key", "tiramisu"); + } + return getParcelledBundle(source); + } + + /** + * Take a bundle, write it to a parcel and return the parcel. + */ + private Parcel getParcelledBundle(Bundle bundle) { + final Parcel p = Parcel.obtain(); + // Don't use p.writeParcelabe(), which would write the creator, which we don't need. + bundle.writeToParcel(p, 0); + p.setDataPosition(0); + return p; + } + + private static class CustomParcelable implements Parcelable { + public final int integer; + public final String string; + + CustomParcelable(int integer, String string) { + this.integer = integer; + this.string = string; + } + + protected CustomParcelable(Parcel in) { + integer = in.readInt(); + string = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(integer); + out.writeString(string); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof CustomParcelable)) { + return false; + } + CustomParcelable that = (CustomParcelable) other; + return integer == that.integer && string.equals(that.string); + } + + @Override + public int hashCode() { + return Objects.hash(integer, string); + } + + public static final Creator<CustomParcelable> CREATOR = new Creator<CustomParcelable>() { + @Override + public CustomParcelable createFromParcel(Parcel in) { + return new CustomParcelable(in); + } + @Override + public CustomParcelable[] newArray(int size) { + return new CustomParcelable[size]; + } + }; + } +} diff --git a/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java b/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java index fa4aa803c75e..ed857e8fc960 100644 --- a/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java +++ b/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java @@ -88,26 +88,15 @@ public class SizeConfigurationBucketsTest { } /** - * Tests that null size configuration buckets unflips the correct configuration flags. + * Tests that {@code null} size configuration buckets do not unflip the configuration flags. */ @Test public void testNullSizeConfigurationBuckets() { - // Check that all 3 size configurations are filtered out of the diff if the buckets are null - // and non-size attributes of screen layout are unchanged. Add a non-size related config - // change (i.e. CONFIG_LOCALE) to test that the diff is not set to zero. final int diff = CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_SCREEN_LAYOUT | CONFIG_LOCALE; final int filteredDiffNonSizeLayoutUnchanged = SizeConfigurationBuckets.filterDiff(diff, Configuration.EMPTY, Configuration.EMPTY, null); - assertEquals(CONFIG_LOCALE, filteredDiffNonSizeLayoutUnchanged); - - // Check that only screen size and smallest screen size are filtered out of the diff if the - // buckets are null and non-size attributes of screen layout are changed. - final Configuration newConfig = new Configuration(); - newConfig.screenLayout |= SCREENLAYOUT_ROUND_YES; - final int filteredDiffNonSizeLayoutChanged = SizeConfigurationBuckets.filterDiff(diff, - Configuration.EMPTY, newConfig, null); - assertEquals(CONFIG_SCREEN_LAYOUT | CONFIG_LOCALE, filteredDiffNonSizeLayoutChanged); + assertEquals(diff, filteredDiffNonSizeLayoutUnchanged); } /** diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 41791afa45a3..2f79caeec7ba 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -43,6 +43,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; +import android.os.SystemProperties; import android.util.ArraySet; import android.util.Log; import android.util.Pair; @@ -70,6 +71,8 @@ import java.util.function.Consumer; public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, ActivityEmbeddingComponent { static final String TAG = "SplitController"; + static final boolean ENABLE_SHELL_TRANSITIONS = + SystemProperties.getBoolean("persist.wm.debug.shell_transit", false); @VisibleForTesting @GuardedBy("mLock") @@ -332,6 +335,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen * bounds is large enough for at least one split rule. */ private void updateAnimationOverride(@NonNull TaskContainer taskContainer) { + if (ENABLE_SHELL_TRANSITIONS) { + // TODO(b/207070762): cleanup with legacy app transition + // Animation will be handled by WM Shell with Shell transition enabled. + return; + } if (!taskContainer.isTaskBoundsInitialized() || !taskContainer.isWindowingModeInitialized()) { // We don't know about the Task bounds/windowingMode yet. diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java index 1ac33173668b..c4f37091a491 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java @@ -83,9 +83,9 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { if (TaskFragmentAnimationController.DEBUG) { - Log.v(TAG, "onAnimationCancelled"); + Log.v(TAG, "onAnimationCancelled: isKeyguardOccluded=" + isKeyguardOccluded); } mHandler.post(this::cancelAnimation); } diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index e7bc74a1744f..6959a591338c 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tik om hierdie program te herbegin en maak volskerm oop."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tik om hierdie program te herbegin vir ’n beter aansig."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerakwessies?\nTik om aan te pas"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 8b2a89238584..fe22b2ce3278 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string> - <string name="restart_button_description" msgid="5887656107651190519">"ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string> + <string name="restart_button_description" msgid="6712141648865547958">"ለተሻለ ዕይታ ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ።"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"የካሜራ ችግሮች አሉ?\nዳግም ለማበጀት መታ ያድርጉ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 2afce7fa3c43..2be6f39f9475 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string> - <string name="restart_button_description" msgid="5887656107651190519">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string> + <string name="restart_button_description" msgid="6712141648865547958">"انقر لإعادة تشغيل هذا التطبيق للحصول على عرض أفضل."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"هل هناك مشاكل في الكاميرا؟\nانقر لإعادة الضبط."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ألم يتم حل المشكلة؟\nانقر للعودة"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق."</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index df975751ee31..098ee84de018 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string> - <string name="restart_button_description" msgid="5887656107651190519">"এপ্টো ৰিষ্টাৰ্ট কৰিবলৈ আৰু পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ টিপক।"</string> + <string name="restart_button_description" msgid="6712141648865547958">"উন্নত ভিউৰ বাবে এপ্টো ৰিষ্টাৰ্ট কৰিবলৈ টিপক।"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"কেমেৰাৰ কোনো সমস্যা হৈছে নেকি?\nপুনৰ খাপ খোৱাবলৈ টিপক"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 892be9345e3a..2f49ae6fdafc 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün toxunun."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toxunaraq bu tətbiqi yenidən başladın ki, daha görüntü əldə edəsiniz."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera problemi var?\nBərpa etmək üçün toxunun"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index b34920e0568f..0656fe185013 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 525e46ff371e..702f0abc07ae 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Націсніце, каб перазапусціць гэту праграму для лепшага прагляду."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Праблемы з камерай?\nНацісніце, каб пераабсталяваць"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index e27ec8ee11bb..0de16d37cd69 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Докоснете, за да рестартирате това приложение с цел по-добър изглед."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблеми с камерата?\nДокоснете за ремонтиране"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 0a8b0b746231..9a48d186b231 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string> - <string name="restart_button_description" msgid="5887656107651190519">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও \'ফুল-স্ক্রিন\' মোড ব্যবহার করুন।"</string> + <string name="restart_button_description" msgid="6712141648865547958">"আরও ভাল ভিউয়ের জন্য এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন।"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ক্যামেরা সংক্রান্ত সমস্যা?\nরিফিট করতে ট্যাপ করুন"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index aadbfa434cf4..31e906de7f51 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s kamerom?\nDodirnite da ponovo namjestite"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index ab672460ce1d..ca0a4211c435 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toca per reiniciar aquesta aplicació i passar a pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tens problemes amb la càmera?\nToca per resoldre\'ls"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index d7b1a3889806..e8772fe269b6 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string> + <string name="restart_button_description" msgid="6712141648865547958">"Klepnutím tuto aplikaci kvůli lepšímu zobrazení restartujete."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s fotoaparátem?\nKlepnutím vyřešíte"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index c0acc08cde19..2b55d4d688ac 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tryk for at genstarte denne app, og gå til fuld skærm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tryk for at genstarte denne app, så visningen forbedres."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index e06bebda8bdf..03eee024f3be 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tippe, um die App im Vollbildmodus neu zu starten."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tippe, um diese App neu zu starten und die Ansicht zu verbessern."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Probleme mit der Kamera?\nZum Anpassen tippen."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 0d9d3eab591b..49bfdf18b1e6 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Πατήστε για να επανεκκινήσετε αυτή την εφαρμογή για καλύτερη προβολή."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Προβλήματα με την κάμερα;\nΠατήστε για επιδιόρθωση."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 48525cd10749..081a01a49249 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 48525cd10749..081a01a49249 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 48525cd10749..081a01a49249 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 48525cd10749..081a01a49249 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index fb6db5f91a25..afc14b821d62 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 3db353a0b4ea..b376b7881333 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Presiona para reiniciar esta app y tener una mejor vista."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Tienes problemas con la cámara?\nPresiona para reajustarla"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index c2493287bcb8..79c1f90a4b8d 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 0133336e58b8..a7fead6af9aa 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 71ccad59e71a..e7530c9690a7 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Saka ezazu aplikazioa berrabiarazteko, eta ezarri pantaila osoko modua."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Hobeto ikusteko, sakatu hau aplikazioa berrabiarazteko."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 20045eff330c..66a657e36c13 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string> - <string name="restart_button_description" msgid="5887656107651190519">"برای بازراهاندازی این برنامه و تغییر به حالت تمامصفحه، ضربه بزنید."</string> + <string name="restart_button_description" msgid="6712141648865547958">"برای داشتن نمایی بهتر، ضربه بزنید تا این برنامه بازراهاندازی شود."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه ضربه بزنید"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن ضربه بزنید"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن ضربه بزنید."</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 2cd265ea82f0..eaf369ad0486 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Onko kameran kanssa ongelmia?\nKorjaa napauttamalla"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index eb25a8d16434..8f614c56db14 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Touchez pour redémarrer cette application et passer en plein écran."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 53358b7a23b7..ec3e1b33a4fa 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Appuyez pour redémarrer cette appli et avoir une meilleure vue."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo ?\nAppuyez pour réajuster"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 09977a194fea..651353d89319 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index 8e9f086daa97..3543be0bda07 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string> - <string name="restart_button_description" msgid="5887656107651190519">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string> + <string name="restart_button_description" msgid="6712141648865547958">"વધુ સારા વ્યૂ માટે, આ ઍપને ફરી શરૂ કરવા ટૅપ કરો."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"કૅમેરામાં સમસ્યાઓ છે?\nફરીથી ફિટ કરવા માટે ટૅપ કરો"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 3d83005ba30b..0f2d38bfeb65 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -72,7 +72,8 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string> - <string name="restart_button_description" msgid="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</string> + <!-- no translation found for restart_button_description (6712141648865547958) --> + <skip /> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 1c4116d6cc8a..cb4f424cf317 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s fotoaparatom?\nDodirnite za popravak"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index d749775a2160..635f4dad8f89 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string> + <string name="restart_button_description" msgid="6712141648865547958">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 160651ca67ad..da382c113797 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string> - <string name="restart_button_description" msgid="5887656107651190519">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string> + <string name="restart_button_description" msgid="6712141648865547958">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար։"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index fab34868009e..cd795390128b 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Masalah kamera?\nKetuk untuk memperbaiki"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index c22b88138714..37141b74005c 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ýta til að endurræsa forritið og fá betri sýn."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Myndavélavesen?\nÝttu til að breyta stærð"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 7ec13c4248e0..b63e76466b6e 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -72,7 +72,8 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tocca per riavviare l\'app e passare alla modalità a schermo intero."</string> + <!-- no translation found for restart_button_description (6712141648865547958) --> + <skip /> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 8625a2a079da..0e500eafd805 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string> - <string name="restart_button_description" msgid="5887656107651190519">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string> + <string name="restart_button_description" msgid="6712141648865547958">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר להקיש כדי לסגור."</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 4d09b202ca06..34ed9c72da0e 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string> - <string name="restart_button_description" msgid="5887656107651190519">"タップしてこのアプリを再起動すると、全画面表示になります。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"タップしてこのアプリを再起動すると、表示が適切になります。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"カメラに関する問題の場合は、\nタップすると修正できます"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 8cbc3d893bd8..14b26c1932cc 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string> - <string name="restart_button_description" msgid="5887656107651190519">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string> + <string name="restart_button_description" msgid="6712141648865547958">"შეეხეთ, რომ გადატვირთოთ ეს აპი უკეთესი ხედისთვის."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"კამერად პრობლემები აქვს?\nშეეხეთ გამოსასწორებლად"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 22cf08b92082..c42efdc4cf25 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ыңғайлы көріністі реттеу үшін қолданбаны түртіп, өшіріп қосыңыз."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 1e72d4fe145f..302b25e5bad2 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោលសារលេចឡើង។"</string> - <string name="restart_button_description" msgid="5887656107651190519">"ចុចដើម្បីចាប់ផ្ដើមកម្មវិធីនេះឡើងវិញ រួចចូលប្រើពេញអេក្រង់។"</string> + <string name="restart_button_description" msgid="6712141648865547958">"ចុចដើម្បីចាប់ផ្ដើមកម្មវិធីនេះឡើងវិញសម្រាប់ទិដ្ឋភាពកាន់តែប្រសើរ។"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"មានបញ្ហាពាក់ព័ន្ធនឹងកាមេរ៉ាឬ?\nចុចដើម្បីដោះស្រាយ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបានដោះស្រាយបញ្ហានេះទេឬ?\nចុចដើម្បីត្រឡប់"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមានបញ្ហាពាក់ព័ន្ធនឹងកាមេរ៉ាទេឬ? ចុចដើម្បីច្រានចោល។"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 24d0c8257b7b..2b3aa0791336 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string> - <string name="restart_button_description" msgid="5887656107651190519">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="restart_button_description" msgid="6712141648865547958">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿವೆಯೇ?\nಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 15e8a9041202..5505955db71a 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string> - <string name="restart_button_description" msgid="5887656107651190519">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string> + <string name="restart_button_description" msgid="6712141648865547958">"보기를 개선하려면 탭하여 앱을 다시 시작합니다."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 94ea9fb9f950..d45a9848abc4 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн таптап коюңуз."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Жакшыраак көрүү үчүн бул колдонмону өчүрүп күйгүзүңүз. Ал үчүн таптап коюңуз."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада маселелер келип чыктыбы?\nОңдоо үчүн таптаңыз"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index be72d8e2a22f..0eeee906070b 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string> - <string name="restart_button_description" msgid="5887656107651190519">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string> + <string name="restart_button_description" msgid="6712141648865547958">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ເພື່ອມຸມມອງທີ່ດີຂຶ້ນ."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ?\nແຕະເພື່ອປັບໃໝ່"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອປິດໄວ້."</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 3fa163bb35c2..fc118e217481 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Palieskite, kad paleistumėte iš naujo šią programą ir įjungtumėte viso ekrano režimą."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 90cd4bed63f8..cd2af07beb7e 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 56e9b406fe8d..c0dff00e6a7c 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Допрете за да ја рестартирате апликацијава за подобар приказ."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми со камерата?\nДопрете за да се совпадне повторно"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index 88e49e78d925..52ea1c7c3150 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string> - <string name="restart_button_description" msgid="5887656107651190519">"ഈ ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്ത് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ടാപ്പ് ചെയ്യുക."</string> + <string name="restart_button_description" msgid="6712141648865547958">"മികച്ച കാഴ്ചയ്ക്കായി ഈ ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ക്യാമറ പ്രശ്നങ്ങളുണ്ടോ?\nശരിയാക്കാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 7a6f62577e63..fd4c4aab1832 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Харагдах байдлыг сайжруулахын тулд энэ аппыг товшиж, дахин эхлүүлнэ үү."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерын асуудал гарсан уу?\nДахин тааруулахын тулд товшино уу"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index c2a947542f0a..b9a165eb6b11 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string> - <string name="restart_button_description" msgid="5887656107651190519">"हे अॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string> + <string name="restart_button_description" msgid="6712141648865547958">"अधिक चांगल्या व्ह्यूसाठी हे अॅप रीस्टार्ट करण्याकरिता टॅप करा."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"कॅमेराशी संबंधित काही समस्या आहेत का?\nपुन्हा फिट करण्यासाठी टॅप करा"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्यासाठी टॅप करा."</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 35512c1c75bb..3d81c9a551fa 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Isu kamera?\nKetik untuk memuatkan semula"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 5aea49f59e2f..50adfe98d8f9 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string> - <string name="restart_button_description" msgid="5887656107651190519">"ဤအက်ပ်ကို ပြန်စပြီး ဖန်သားပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string> + <string name="restart_button_description" msgid="6712141648865547958">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဤအက်ပ်ပြန်စရန် တို့နိုင်သည်။"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ကင်မရာပြဿနာလား။\nပြင်ဆင်ရန် တို့ပါ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 8e87bc10c470..74e066ec11fd 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Trykk for å starte denne appen på nytt for bedre visning."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du kameraproblemer?\nTrykk for å tilpasse"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 831f6e2ef829..b257f9e6d0d3 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string> - <string name="restart_button_description" msgid="5887656107651190519">"यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string> + <string name="restart_button_description" msgid="6712141648865547958">"यो एप अझ राम्रो हेर्न मिल्ने बनाउनका लागि यसलाई रिस्टार्ट गर्न ट्याप गर्नुहोस्।"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्यामेरासम्बन्धी समस्या देखियो?\nसमस्या हल गर्न ट्याप गर्नुहोस्"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index affdd0e2a223..6ea24a8b3808 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tik om deze app opnieuw op te starten voor een betere weergave."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Cameraproblemen?\nTik om opnieuw passend te maken."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index f150cb9a9160..f8c924828d50 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string> - <string name="restart_button_description" msgid="5887656107651190519">"ଏହି ଆପକୁ ରିଷ୍ଟାର୍ଟ କରି ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> + <string name="restart_button_description" msgid="6712141648865547958">"ଏକ ଆହୁରି ଭଲ ଭ୍ୟୁ ପାଇଁ ଏହି ଆପ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"କ୍ୟାମେରାରେ ସମସ୍ୟା ଅଛି?\nପୁଣି ଫିଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 62587e58edc9..b80da0ba4e57 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string> - <string name="restart_button_description" msgid="5887656107651190519">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string> + <string name="restart_button_description" msgid="6712141648865547958">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਲਈ ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ?\nਮੁੜ-ਫਿੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 363c851ca4cd..bdd44dd8a743 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string> - <string name="restart_button_description" msgid="5887656107651190519">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Kliknij, aby zrestartować aplikację i zyskać lepszą widoczność."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemy z aparatem?\nKliknij, aby dopasować"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index f328b6c3a781..b9e41eae5de9 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 67369b8b0175..c1e57d8c9c97 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index f328b6c3a781..b9e41eae5de9 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 8da1d67f9841..c49bf9dc231c 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionați"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Atingeți ca să reporniți aplicația pentru o vizualizare mai bună."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Aveți probleme cu camera foto?\nAtingeți pentru a reîncadra"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ați remediat problema?\nAtingeți pentru a reveni"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu aveți probleme cu camera foto? Atingeți pentru a închide."</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 49efac67ceb0..ffe031d86725 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Нажмите, чтобы перезапустить приложение и настроить удобный для просмотра вид"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблемы с камерой?\nНажмите, чтобы исправить."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 1f8cba85c9eb..b27e1b9bc94a 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string> - <string name="restart_button_description" msgid="5887656107651190519">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න."</string> + <string name="restart_button_description" msgid="6712141648865547958">"වඩා හොඳ දසුනක් ලබා ගැනීම සඳහා මෙම යෙදුම යළි ඇරඹීමට තට්ටු කරන්න."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"කැමරා ගැටලුද?\nයළි සවි කිරීමට තට්ටු කරන්න"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්රතිවර්තනය කිරීමට තට්ටු කරන්න"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index ca14dd78aaa5..b5bedf79f3ba 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s kamerou?\nKlepnutím znova upravte."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 626be8beb04d..ac926b9ee8db 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index 591f4b71b00c..07c52fe4251a 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Trokit për të rifilluar këtë aplikacion për një pamje më të mirë."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ka probleme me kamerën?\nTrokit për ta ripërshtatur"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index fdd49b5542c7..0289dd105ee5 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Додирните да бисте рестартовали ову апликацију ради бољег приказа."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 54384ca14db9..cfdb1ddcf377 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tryck för att starta om appen i helskärmsläge."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tryck för att starta om appen och få en bättre vy."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problem med kameran?\nTryck för att anpassa på nytt"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 2f7d2246f939..383e9bb6bbfa 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Gusa ili uzime na uwashe programu hii, kisha nenda kwenye skrini nzima."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Je, kuna hitilafu za kamera?\nGusa ili urekebishe"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index b6269946ab32..cc512f3c48aa 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string> - <string name="restart_button_description" msgid="5887656107651190519">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string> + <string name="restart_button_description" msgid="6712141648865547958">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index f0803507b5fc..cdbe021add47 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string> - <string name="restart_button_description" msgid="5887656107651190519">"ఈ యాప్ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేసి, ఆపై పూర్తి స్క్రీన్లోకి వెళ్లండి."</string> + <string name="restart_button_description" msgid="6712141648865547958">"మెరుగైన వీక్షణ కోసం ఈ యాప్ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేయండి."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"కెమెరా సమస్యలు ఉన్నాయా?\nరీఫిట్ చేయడానికి ట్యాప్ చేయండి"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 0d1f23b1d350..136a81c06c4f 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string> - <string name="restart_button_description" msgid="5887656107651190519">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string> + <string name="restart_button_description" msgid="6712141648865547958">"แตะเพื่อรีสตาร์ทแอปนี้และรับมุมมองที่ดียิ่งขึ้น"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"หากพบปัญหากับกล้อง\nแตะเพื่อแก้ไข"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"หากไม่พบปัญหากับกล้อง แตะเพื่อปิด"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index bfae45afeb5d..4d32af36cabe 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string> - <string name="restart_button_description" msgid="5887656107651190519">"I-tap para i-restart ang app na ito at mag-full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"I-tap para i-restart ang app na ito para sa mas magandang view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"May mga isyu sa camera?\nI-tap para i-refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 6a9be8048505..f3ab37065270 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kameranızda sorun mu var?\nDüzeltmek için dokunun"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 52f6d1145245..d7d82cb56ac5 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Натисніть, щоб перезапустити цей додаток для зручнішого перегляду."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми з камерою?\nНатисніть, щоб пристосувати"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблему не вирішено?\nНатисніть, щоб скасувати зміни"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немає проблем із камерою? Торкніться, щоб закрити."</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 3abfb0d4fa65..4a8476aebe18 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string> - <string name="restart_button_description" msgid="5887656107651190519">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string> + <string name="restart_button_description" msgid="6712141648865547958">"بہتر منظر کے لیے اس ایپ کو ری اسٹارٹ کرنے کی خاطر تھپتھپائیں۔"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"کیمرے کے مسائل؟\nدوبارہ فٹ کرنے کیلئے تھپتھپائیں"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 0c0771f870dd..8a4eac3bb657 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu ilovani qaytadan ishga tushirish va butun ekranda ochish uchun bosing."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera nosozmi?\nQayta moslash uchun bosing"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 8b692a71dd27..2f8fe6076c68 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Nhấn để khởi động lại ứng dụng này để xem tốt hơn."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 8fed6bfb3eed..ab44fb1d2488 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭对话泡。"</string> - <string name="restart_button_description" msgid="5887656107651190519">"点按即可重启此应用并进入全屏模式。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"点按即可重启此应用,获得更好的视图体验。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相机有问题?\n点按即可整修"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"没有解决此问题?\n点按即可恢复"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相机没有问题?点按即可忽略。"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index add329188515..b4bc3909c08f 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string> - <string name="restart_button_description" msgid="5887656107651190519">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"請輕觸並重新啟動此應用程式,取得更良好的觀看體驗。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題?\n輕按即可修正"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index f2c2a2970d8b..45de4156084b 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string> - <string name="restart_button_description" msgid="5887656107651190519">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"請輕觸並重新啟動此應用程式,取得更良好的觀看體驗。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題嗎?\n輕觸即可修正"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 94e5b9bf4529..7c31a166e825 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java index 4eba1697b595..cf2734c375f2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java @@ -591,7 +591,7 @@ public class PipAnimationController { final Rect insets = computeInsets(fraction); getSurfaceTransactionHelper().scaleAndCrop(tx, leash, sourceHintRect, initialSourceValue, bounds, insets, - isInPipDirection); + isInPipDirection, fraction); if (shouldApplyCornerRadius()) { final Rect sourceBounds = new Rect(initialContainerRect); sourceBounds.inset(insets); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java index a017a2674359..c0bc108baada 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java @@ -104,7 +104,7 @@ public class PipSurfaceTransactionHelper { public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx, SurfaceControl leash, Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets, - boolean isInPipDirection) { + boolean isInPipDirection, float fraction) { mTmpDestinationRect.set(sourceBounds); // Similar to {@link #scale}, we want to position the surface relative to the screen // coordinates so offset the bounds to 0,0 @@ -116,9 +116,13 @@ public class PipSurfaceTransactionHelper { if (isInPipDirection && sourceRectHint != null && sourceRectHint.width() < sourceBounds.width()) { // scale by sourceRectHint if it's not edge-to-edge, for entering PiP transition only. - scale = sourceBounds.width() <= sourceBounds.height() + final float endScale = sourceBounds.width() <= sourceBounds.height() ? (float) destinationBounds.width() / sourceRectHint.width() : (float) destinationBounds.height() / sourceRectHint.height(); + final float startScale = sourceBounds.width() <= sourceBounds.height() + ? (float) destinationBounds.width() / sourceBounds.width() + : (float) destinationBounds.height() / sourceBounds.height(); + scale = (1 - fraction) * startScale + fraction * endScale; } else { scale = sourceBounds.width() <= sourceBounds.height() ? (float) destinationBounds.width() / sourceBounds.width() 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 37c0c9b01c88..22b0ccbc8488 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 @@ -1472,6 +1472,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, "%s: Abort animation, invalid leash", TAG); return null; } + if (isInPipDirection(direction) + && !isSourceRectHintValidForEnterPip(sourceHintRect, destinationBounds)) { + // The given source rect hint is too small for enter PiP animation, reset it to null. + sourceHintRect = null; + } final int rotationDelta = mWaitForFixedRotation ? deltaRotation(mCurrentRotation, mNextRotation) : Surface.ROTATION_0; @@ -1546,6 +1551,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } /** + * This is a situation in which the source rect hint on at least one axis is smaller + * than the destination bounds, which represents a problem because we would have to scale + * up that axis to fit the bounds. So instead, just fallback to the non-source hint + * animation in this case. + * + * @return {@code false} if the given source is too small to use for the entering animation. + */ + private boolean isSourceRectHintValidForEnterPip(Rect sourceRectHint, Rect destinationBounds) { + return sourceRectHint != null + && sourceRectHint.width() > destinationBounds.width() + && sourceRectHint.height() > destinationBounds.height(); + } + + /** * Sync with {@link SplitScreenController} on destination bounds if PiP is going to * split screen. * diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java index dc60bcf742ce..29434f73e84b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java @@ -116,7 +116,7 @@ public class PipUtils { if (taskId <= 0) return null; try { return ActivityTaskManager.getService().getTaskSnapshot( - taskId, isLowResolution); + taskId, isLowResolution, false /* takeSnapshotIfNeeded */); } catch (RemoteException e) { Log.e(TAG, "Failed to get task snapshot, taskId=" + taskId, e); return null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 4e7b20e3ae84..59b0afe22acb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -457,10 +457,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { onRemoteAnimationFinishedOrCancelled(evictWct); try { - adapter.getRunner().onAnimationCancelled(); + adapter.getRunner().onAnimationCancelled(isKeyguardOccluded); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 05e5b8e66a00..dcd6277966dd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -866,13 +866,19 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { }); }; va.addListener(new AnimatorListenerAdapter() { + private boolean mFinished = false; + @Override public void onAnimationEnd(Animator animation) { + if (mFinished) return; + mFinished = true; finisher.run(); } @Override public void onAnimationCancel(Animator animation) { + if (mFinished) return; + mFinished = true; finisher.run(); } }); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java index 61e11e877b90..61e92f355dc2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java @@ -107,7 +107,7 @@ public class LegacyTransitions { } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { mCancelled = true; mApps = mWallpapers = mNonApps = null; checkApply(); diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt index d4298b8f29a0..49eca63a23ec 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt @@ -25,11 +25,13 @@ import androidx.test.uiautomator.By import androidx.test.uiautomator.BySelector import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until +import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.traces.common.FlickerComponentName import com.android.server.wm.traces.parser.toFlickerComponent import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME import com.android.wm.shell.flicker.testapp.Components +import org.junit.Assert class SplitScreenHelper( instrumentation: Instrumentation, @@ -187,5 +189,23 @@ class SplitScreenHelper( SystemClock.sleep(GESTURE_STEP_MS) } } + + fun createShortcutOnHotseatIfNotExist( + taplInstrumentation: LauncherInstrumentation, + appName: String + ) { + taplInstrumentation.workspace + .deleteAppIcon(taplInstrumentation.workspace.getHotseatAppIcon(0)) + val allApps = taplInstrumentation.workspace.switchToAllApps() + allApps.freeze() + try { + val appIconSrc = allApps.getAppIcon(appName) + Assert.assertNotNull("Unable to find app icon", appIconSrc) + val appIconDest = appIconSrc.dragToHotseat(0) + Assert.assertNotNull("Unable to drag app icon on hotseat", appIconDest) + } finally { + allApps.unfreeze() + } + } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index b4267ffced5c..9ba51661aa5f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -77,11 +76,6 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec } } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - /** * Checks [pipApp] window remains visible throughout the animation */ diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt index accb524d3de1..f50097d4ce84 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt @@ -28,13 +28,12 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.traces.common.FlickerComponentName import com.android.wm.shell.flicker.helpers.FixedAppHelper import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT -import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION +import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -114,14 +113,6 @@ class EnterPipToOtherOrientationTest( override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() /** - * Checks that the [FlickerComponentName.STATUS_BAR] has the correct position at - * the start and end of the transition - */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - - /** * Checks that all parts of the screen are covered at the start and end of the transition * * TODO b/197726599 Prevents all states from being checked diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt index a3ed79bf0409..0768e82e491c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt @@ -79,11 +79,6 @@ class ExitPipViaExpandButtonClickTest( } /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - - /** {@inheritDoc} */ @FlakyTest(bugId = 197726610) @Test override fun pipLayerExpands() = super.pipLayerExpands() diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt index ab07ede5bb32..128703ad332c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt @@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.statusBarLayerRotatesScales import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -78,10 +77,6 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti @Test override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible() - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - /** * Checks that the focus doesn't change between windows during the transition */ @@ -108,4 +103,4 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti repetitions = 3) } } -}
\ No newline at end of file +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 4618fb376f7f..9fad4997e63a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -29,7 +29,6 @@ import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.wm.shell.flicker.helpers.FixedAppHelper import org.junit.FixMethodOrder import org.junit.Test @@ -96,13 +95,6 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() /** - * Checks the position of the status bar at the start and end of the transition - */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - - /** * Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition */ @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt index e40f2bc1ed5a..51339a1deb4b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt @@ -25,9 +25,9 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE import com.android.wm.shell.flicker.testapp.Components @@ -113,10 +113,6 @@ open class SetRequestedOrientationWhilePinnedTest( @Test override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - @Presubmit @Test fun pipWindowInsideDisplay() { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt new file mode 100644 index 000000000000..05c6e24ee89d --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt @@ -0,0 +1,129 @@ +/* + * 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.wm.shell.flicker.splitscreen + +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.wm.shell.flicker.appWindowBecomesVisible +import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import com.android.wm.shell.flicker.layerBecomesVisible +import com.android.wm.shell.flicker.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible +import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible +import org.junit.Assume +import org.junit.Before +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test enter split screen by dragging app icon from taskbar. + * This test is only for large screen devices. + * + * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromTaskbar` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class EnterSplitScreenByDragFromTaskbar( + testSpec: FlickerTestParameter +) : SplitScreenBase(testSpec) { + + @Before + fun before() { + Assume.assumeTrue(taplInstrumentation.isTablet) + } + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + eachRun { + taplInstrumentation.goHome() + SplitScreenHelper.createShortcutOnHotseatIfNotExist( + taplInstrumentation, secondaryApp.appName + ) + primaryApp.launchViaIntent(wmHelper) + } + } + transitions { + taplInstrumentation.launchedAppState.taskbar + .getAppIcon(secondaryApp.appName) + .dragToSplitscreen( + secondaryApp.component.packageName, + primaryApp.component.packageName + ) + } + } + + @Presubmit + @Test + fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + + @Presubmit + @Test + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component) + + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component) + + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + testSpec.endRotation, primaryApp.component, false /* splitLeftTop */ + ) + + @Presubmit + @Test + fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( + testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */ + ) + + @Presubmit + @Test + fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component) + + @Presubmit + @Test + fun secondaryAppWindowBecomesVisible() = + testSpec.appWindowBecomesVisible(secondaryApp.component) + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + repetitions = SplitScreenHelper.TEST_REPETITIONS, + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) + ) + } + } +} diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl index b136d5bc4db3..2bdd5c8bc977 100644 --- a/media/java/android/media/projection/IMediaProjection.aidl +++ b/media/java/android/media/projection/IMediaProjection.aidl @@ -17,7 +17,7 @@ package android.media.projection; import android.media.projection.IMediaProjectionCallback; -import android.window.WindowContainerToken; +import android.os.IBinder; /** {@hide} */ interface IMediaProjection { @@ -31,14 +31,14 @@ interface IMediaProjection { void unregisterCallback(IMediaProjectionCallback callback); /** - * Returns the {@link android.window.WindowContainerToken} identifying the task to record, or - * {@code null} if there is none. + * Returns the {@link android.os.IBinder} identifying the task to record, or {@code null} if + * there is none. */ - WindowContainerToken getTaskRecordingWindowContainerToken(); + IBinder getLaunchCookie(); /** - * Updates the {@link android.window.WindowContainerToken} identifying the task to record, or - * {@code null} if there is none. + * Updates the {@link android.os.IBinder} identifying the task to record, or {@code null} if + * there is none. */ - void setTaskRecordingWindowContainerToken(in WindowContainerToken token); + void setLaunchCookie(in IBinder launchCookie); } diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java index ba7bf3f5f5d3..ae44fc575f7c 100644 --- a/media/java/android/media/projection/MediaProjection.java +++ b/media/java/android/media/projection/MediaProjection.java @@ -25,13 +25,13 @@ import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.hardware.display.VirtualDisplayConfig; import android.os.Handler; +import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; import android.view.ContentRecordingSession; import android.view.Surface; -import android.window.WindowContainerToken; import java.util.Map; @@ -172,18 +172,16 @@ public final class MediaProjection { @NonNull VirtualDisplayConfig.Builder virtualDisplayConfig, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) { try { - final WindowContainerToken taskWindowContainerToken = - mImpl.getTaskRecordingWindowContainerToken(); + final IBinder launchCookie = mImpl.getLaunchCookie(); Context windowContext = null; ContentRecordingSession session; - if (taskWindowContainerToken == null) { + if (launchCookie == null) { windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(), TYPE_APPLICATION, null /* options */); session = ContentRecordingSession.createDisplaySession( windowContext.getWindowContextToken()); } else { - session = ContentRecordingSession.createTaskSession( - taskWindowContainerToken.asBinder()); + session = ContentRecordingSession.createTaskSession(launchCookie); } virtualDisplayConfig.setWindowManagerMirroring(true); final DisplayManager dm = mContext.getSystemService(DisplayManager.class); diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml index e01916ee3fc0..2456f63f1b34 100644 --- a/packages/CompanionDeviceManager/res/values-km/strings.xml +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -39,7 +39,7 @@ <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_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/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml index 2c53626e55f8..88d55f2ff32a 100644 --- a/packages/InputDevices/res/values-zu/strings.xml +++ b/packages/InputDevices/res/values-zu/strings.xml @@ -3,51 +3,51 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="8016145283189546017">"Amadivayisi wokufaka"</string> <string name="keyboard_layouts_label" msgid="6688773268302087545">"Ikhibhodi ye-Android"</string> - <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"I-English (UK)"</string> - <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"I-English (US)"</string> - <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"I-English (US), isitayela sakwamanye amazwe"</string> - <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"I-English (US), isitayela se-Colemak"</string> - <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"I-English (US), isitayela se-Dvorak"</string> - <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"I-English (US), isitayela sokusebenza"</string> - <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Isi-German"</string> - <string name="keyboard_layout_french_label" msgid="813450119589383723">"Isi-French"</string> - <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Isi-French (Canada)"</string> + <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string> + <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string> + <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), isitayela sakwamanye amazwe"</string> + <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), isitayela se-Colemak"</string> + <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), isitayela se-Dvorak"</string> + <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"English (US), isitayela sokusebenza"</string> + <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string> + <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string> + <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string> <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Isi-Russian"</string> <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Isi-Russian, isitayela se-Mac"</string> - <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Isi-Spanish"</string> + <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string> <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Isi-Swiss French"</string> <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Isi-Swiss German"</string> <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Isi-Belgian"</string> <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Isi-Bulgarian"</string> <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"Isi-Bulgarian, Ifonetiki"</string> - <string name="keyboard_layout_italian" msgid="6497079660449781213">"Isi-Italian"</string> - <string name="keyboard_layout_danish" msgid="8036432066627127851">"Isi-Danish"</string> - <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Isi-Norwegian"</string> - <string name="keyboard_layout_swedish" msgid="732959109088479351">"Isi-Swedish"</string> - <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Isi-Finnish"</string> + <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string> + <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string> + <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string> + <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string> + <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string> <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Isi-Croatian"</string> - <string name="keyboard_layout_czech" msgid="1349256901452975343">"Isi-Czech"</string> + <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string> <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Isitayela se-Czech QWERTY"</string> <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Isi-Estonian"</string> - <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Isi-Hungarian"</string> - <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isi-Icelandic"</string> + <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string> + <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string> <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Isi-Brazilian"</string> - <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Isi-Portuguese"</string> + <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string> <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Isi-Slovak"</string> - <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Isi-Slovenian"</string> - <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Isi-Turkish"</string> + <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string> + <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string> <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"I-Turkish-F"</string> <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Isi-Ukrainian"</string> - <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Isi-Arabic"</string> - <string name="keyboard_layout_greek" msgid="7289253560162386040">"Isi-Greek"</string> - <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Isi-Hebrew"</string> - <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Isi-Lithuanian"</string> - <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Isi-Spanish (Latin)"</string> - <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Isi-Latvian"</string> - <string name="keyboard_layout_persian" msgid="3920643161015888527">"Isi-Persian"</string> - <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Isi-Azebhayijani"</string> - <string name="keyboard_layout_polish" msgid="1121588624094925325">"Isi-Polish"</string> - <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Isi-Belarusian"</string> + <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabic"</string> + <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greek"</string> + <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrew"</string> + <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lithuanian"</string> + <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanish (Latin)"</string> + <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latvian"</string> + <string name="keyboard_layout_persian" msgid="3920643161015888527">"Persian"</string> + <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerbaijani"</string> + <string name="keyboard_layout_polish" msgid="1121588624094925325">"Polish"</string> + <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"isi-Mongolian"</string> - <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Okwesi-Georgian"</string> + <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> </resources> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 946bbb512f1c..e6337663ad35 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -576,7 +576,7 @@ <string name="user_setup_dialog_message" msgid="269931619868102841">"مطمئن شوید شخص در دسترس است تا دستگاه را بگیرد و فضایش را تنظیم کند"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"اکنون نمایه را تنظیم میکنید؟"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"اکنون تنظیم شود"</string> - <string name="user_setup_button_setup_later" msgid="8712980133555493516">"اکنون نه"</string> + <string name="user_setup_button_setup_later" msgid="8712980133555493516">"حالا نه"</string> <string name="user_add_user_type_title" msgid="551279664052914497">"افزودن"</string> <string name="user_new_user_name" msgid="60979820612818840">"کاربر جدید"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"نمایه جدید"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 475178ef726b..4b2c602f4162 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -100,13 +100,13 @@ <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> - <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Идэвхтэй, Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string> <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Идэвхтэй, зөвхөн зүүн тал"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index c3dac352ad25..1b43ad472d8b 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -183,8 +183,8 @@ <string name="running_process_item_user_label" msgid="3988506293099805796">"အသုံးပြုသူ- <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"မူရင်း သတ်မှတ်မထားပါ။"</string> - <string name="tts_settings" msgid="8130616705989351312">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"စာသားမှ စကားပြောသို့ အထွက်"</string> + <string name="tts_settings" msgid="8130616705989351312">"စာ-မှ-စကားပြောင်းခြင်း ဆက်တင်များ"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"စာ-မှ-စကားသို့ အထွက်"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"စကားပြောနှုန်း"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"စာတမ်းအားပြောဆိုသော အမြန်နှုန်း"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"အသံအနိမ့်အမြင့်"</string> @@ -198,7 +198,7 @@ <string name="tts_install_data_title" msgid="1829942496472751703">"အသံဒေတာများကို ထည့်သွင်းခြင်း"</string> <string name="tts_install_data_summary" msgid="3608874324992243851">"စကားသံပေါင်းစပ်မှုအတွက်လိုအပ်သောအသံဒေတာအား ထည့်သွင်းမည်"</string> <string name="tts_engine_security_warning" msgid="3372432853837988146">"ဤစကားသံပေါင်းစပ်စနစ်အားအသုံးပြုရာရာတွင် သင့်ကိုယ်ရေးအချက်အလက်များဖြစ်သော စကားဝှက်များနှင့် ကရက်ဒစ်ကတ်နံပါတ်စသည်တို့အပါအဝင် သင်ပြောဆိုသောစာသားများအားလုံးကို ရယူသွားမည်ဖြစ်သည်။ ဤစနစ်သည် <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> မှ လာပါသည်။ ဤစကားသံပေါင်းစပ်စနစ်ကို အသုံးပြုမလား။"</string> - <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာသားမှ အသံထွက်ရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string> + <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာ-မှ-စကား ပြောင်းရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string> <string name="tts_default_sample_string" msgid="6388016028292967973">"ဤသည်မှာ အသံတုလုပ်ခြင်း ၏ နမူနာတစ်ခုဖြစ်သည်။"</string> <string name="tts_status_title" msgid="8190784181389278640">"လက်ရှိဘာသာစကားအခြေအနေ"</string> <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> သည်အပြည့်အ၀ အထောက်အကူပြုသည်။"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 2ebf1d71e133..e2cb7924481c 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -184,7 +184,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"Algumas predefinições definidas"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"Nenhuma predefinição definida"</string> <string name="tts_settings" msgid="8130616705989351312">"Definições de texto para voz"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"Saída de síntese de voz"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"Saída de conversão de texto em voz"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"Taxa de voz"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"Velocidade a que o texto é falado"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"Tonalidade"</string> @@ -194,12 +194,12 @@ <string name="tts_lang_not_selected" msgid="7927823081096056147">"Idioma não selecionado"</string> <string name="tts_default_lang_summary" msgid="9042620014800063470">"Define a voz do idioma específico para o texto lido"</string> <string name="tts_play_example_title" msgid="1599468547216481684">"Ouvir um exemplo"</string> - <string name="tts_play_example_summary" msgid="634044730710636383">"Reproduzir uma breve demonstração de síntese de voz"</string> + <string name="tts_play_example_summary" msgid="634044730710636383">"Reproduzir uma breve demonstração de conversão de texto em voz"</string> <string name="tts_install_data_title" msgid="1829942496472751703">"Instalar dados de voz"</string> - <string name="tts_install_data_summary" msgid="3608874324992243851">"Instalar os dados de voz necessários para a síntese de voz"</string> + <string name="tts_install_data_summary" msgid="3608874324992243851">"Instalar os dados de voz necessários para a conversão de texto em voz"</string> <string name="tts_engine_security_warning" msgid="3372432853837988146">"Este motor de síntese de discurso pode permitir a recolha de todo o texto que será falado, incluindo dados pessoais, como palavras-passe e números de cartão de crédito. O serviço é fornecido com o motor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Permitir a utilização deste motor de síntese de discurso?"</string> - <string name="tts_engine_network_required" msgid="8722087649733906851">"Este idioma requer uma ligação de rede ativa para uma saída de síntese de voz."</string> - <string name="tts_default_sample_string" msgid="6388016028292967973">"Exemplo de síntese de voz."</string> + <string name="tts_engine_network_required" msgid="8722087649733906851">"Este idioma requer uma ligação de rede ativa para uma saída de conversão de texto em voz."</string> + <string name="tts_default_sample_string" msgid="6388016028292967973">"Exemplo de conversão de texto em voz."</string> <string name="tts_status_title" msgid="8190784181389278640">"Estado do idioma predefinido"</string> <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportado"</string> <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> necessita de ligação de rede"</string> diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml index 52554e216436..a5b9f79325fd 100644 --- a/packages/SettingsLib/res/values-te/arrays.xml +++ b/packages/SettingsLib/res/values-te/arrays.xml @@ -151,9 +151,9 @@ </string-array> <string-array name="bluetooth_audio_active_device_summaries"> <item msgid="8019740759207729126"></item> - <item msgid="204248102837117183">", సక్రియంగా ఉంది"</item> - <item msgid="253388653486517049">", (మీడియా) సక్రియంగా ఉంది"</item> - <item msgid="5001852592115448348">", (ఫోన్) సక్రియంగా ఉంది"</item> + <item msgid="204248102837117183">", యాక్టివ్గా ఉంది"</item> + <item msgid="253388653486517049">", (మీడియా) యాక్టివ్గా ఉంది"</item> + <item msgid="5001852592115448348">", (ఫోన్) యాక్టివ్గా ఉంది"</item> </string-array> <string-array name="select_logd_size_titles"> <item msgid="1191094707770726722">"ఆఫ్"</item> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 5963495534fc..bec67ec807ef 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -291,14 +291,14 @@ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"బ్లూటూత్ MAP వెర్షన్"</string> <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"బ్లూటూత్ MAP వెర్షన్ను ఎంచుకోండి"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"బ్లూటూత్ ఆడియో కోడెక్"</string> - <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"బ్లూటూత్ ఆడియో కోడెక్ని సక్రియం చేయండి\nఎంపిక"</string> + <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"బ్లూటూత్ ఆడియో కోడెక్ని యాక్టివేట్ చేయండి\nఎంపిక"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"బ్లూటూత్ ఆడియో శాంపిల్ రేట్"</string> - <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"బ్లూటూత్ ఆడియో కోడెక్ని సక్రియం చేయండి\nఎంపిక: నమూనా రేట్"</string> + <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"బ్లూటూత్ ఆడియో కోడెక్ని యాక్టివేట్ చేయండి\nఎంపిక: నమూనా రేట్"</string> <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"గ్రే-అవుట్ అంటే ఫోన్ లేదా హెడ్సెట్ మద్దతు లేదు అని అర్ధం"</string> <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"ఒక్కో శాంపిల్కు బ్లూటూత్ ఆడియో బిట్లు"</string> - <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"బ్లూటూత్ ఆడియో కోడెక్ని సక్రియం చేయండి\nఎంపిక: ఒక్కో నమూనాలో బిట్లు"</string> + <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"బ్లూటూత్ ఆడియో కోడెక్ని యాక్టివేట్ చేయండి\nఎంపిక: ఒక్కో నమూనాలో బిట్లు"</string> <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"బ్లూటూత్ ఆడియో ఛానెల్ మోడ్"</string> - <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"బ్లూటూత్ ఆడియో కోడెక్ని సక్రియం చేయండి\nఎంపిక: ఛానెల్ మోడ్"</string> + <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"బ్లూటూత్ ఆడియో కోడెక్ని యాక్టివేట్ చేయండి\nఎంపిక: ఛానెల్ మోడ్"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"బ్లూటూత్ ఆడియో LDAC కోడెక్: ప్లేబ్యాక్ క్వాలిటీ"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"బ్లూటూత్ ఆడియో LDAC యాక్టివ్ చేయండి\nకోడెక్ ఎంపిక: ప్లేబ్యాక్ క్వాలిటీ"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"ప్రసారం చేస్తోంది: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> @@ -423,11 +423,11 @@ <string-array name="color_mode_descriptions"> <item msgid="6828141153199944847">"మెరుగైన రంగులు"</item> <item msgid="4548987861791236754">"కంటికి కనిపించే విధంగా సహజమైన రంగులు"</item> - <item msgid="1282170165150762976">"డిజిటల్ కంటెంట్ కోసం అనుకూలీకరించిన రంగులు"</item> + <item msgid="1282170165150762976">"డిజిటల్ కంటెంట్ కోసం అనుకూలంగా మార్చిన రంగులు"</item> </string-array> <string name="inactive_apps_title" msgid="5372523625297212320">"స్టాండ్బై యాప్లు"</string> <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"నిష్క్రియంగా ఉంది. టోగుల్ చేయడానికి నొక్కండి."</string> - <string name="inactive_app_active_summary" msgid="8047630990208722344">"సక్రియంగా ఉంది. టోగుల్ చేయడానికి నొక్కండి."</string> + <string name="inactive_app_active_summary" msgid="8047630990208722344">"యాక్టివ్గా ఉంది. టోగుల్ చేయడానికి నొక్కండి."</string> <string name="standby_bucket_summary" msgid="5128193447550429600">"యాప్ స్టాండ్బై స్థితి:<xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="transcode_settings_title" msgid="2581975870429850549">"మీడియా ట్రాన్స్కోడింగ్ సెట్టింగ్లు"</string> <string name="transcode_user_control" msgid="6176368544817731314">"ట్రాన్స్కోడింగ్ ఆటోమేటిక్ సెట్టింగ్లను ఓవర్రైడ్ చేయండి"</string> @@ -570,7 +570,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"యూజర్"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"పరిమితం చేయబడిన ప్రొఫైల్"</string> <string name="user_add_user_title" msgid="5457079143694924885">"కొత్త యూజర్ను జోడించాలా?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్లను క్రియేట్ చేయడం ద్వారా మీరు ఈ పరికరాన్ని ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్కు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలీకరించవచ్చు. యూజర్లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగిలిన యూజర్లందరి కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెసిబిలిటీ సెట్టింగ్లు, సర్వీస్లు కొత్త యూజర్కి బదిలీ కాకపోవచ్చు."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్లను క్రియేట్ చేయడం ద్వారా మీరు ఈ పరికరాన్ని ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్కు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలంగా మార్చవచ్చు. యూజర్లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగిలిన యూజర్లందరి కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెసిబిలిటీ సెట్టింగ్లు, సర్వీస్లు కొత్త యూజర్కి బదిలీ కాకపోవచ్చు."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"మీరు కొత్త యూజర్ను జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా యూజర్ల కోసం యాప్లను అప్డేట్ చేయగలరు."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"యూజర్ను ఇప్పుడే సెటప్ చేయాలా?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి నిల్వ స్థలాన్ని సెటప్ చేయండి"</string> diff --git a/packages/SettingsProvider/res/values-nb/strings.xml b/packages/SettingsProvider/res/values-nb/strings.xml index 3bdaf83a4230..8da90c0f32cb 100644 --- a/packages/SettingsProvider/res/values-nb/strings.xml +++ b/packages/SettingsProvider/res/values-nb/strings.xml @@ -20,6 +20,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Lagring av innstillinger"</string> - <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for Wi-Fi-sone er endret"</string> + <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for wifi-sone er endret"</string> <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Trykk for å se detaljer"</string> </resources> diff --git a/packages/Shell/res/values-pa/strings.xml b/packages/Shell/res/values-pa/strings.xml index daeac3cf0b04..57ad5e25fb8f 100644 --- a/packages/Shell/res/values-pa/strings.xml +++ b/packages/Shell/res/values-pa/strings.xml @@ -39,7 +39,7 @@ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string> <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string> <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਵੇਰਵੇ"</string> - <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਨਾਮ"</string> + <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਦਾ ਨਾਮ"</string> <string name="bugreport_info_title" msgid="2306030793918239804">"ਬੱਗ ਸਿਰਲੇਖ"</string> <string name="bugreport_info_description" msgid="5072835127481627722">"ਬੱਗ ਸਾਰਾਂਸ਼"</string> <string name="save" msgid="4781509040564835759">"ਰੱਖਿਅਤ ਕਰੋ"</string> diff --git a/packages/SimAppDialog/res/values-fa/strings.xml b/packages/SimAppDialog/res/values-fa/strings.xml index 7eb87dddf41d..74e81a42e675 100644 --- a/packages/SimAppDialog/res/values-fa/strings.xml +++ b/packages/SimAppDialog/res/values-fa/strings.xml @@ -21,6 +21,6 @@ <string name="install_carrier_app_title" msgid="334729104862562585">"سرویس دستگاه همراه را فعال کنید"</string> <string name="install_carrier_app_description" msgid="4014303558674923797">"برای اینکه سیمکارت جدیدتان بهدرستی کار کند، باید برنامه <xliff:g id="ID_1">%1$s</xliff:g> را نصب کنید"</string> <string name="install_carrier_app_description_default" msgid="7356830245205847840">"برای اینکه سیمکارت جدیدتان بهدرستی کار کند، باید برنامه شرکت مخابراتی را نصب کنید"</string> - <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"الآن نه"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"حالا نه"</string> <string name="install_carrier_app_download_action" msgid="7859229305958538064">"بارگیری برنامه"</string> </resources> diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index f05c1e2e76f2..fa87de2b1353 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -93,6 +93,7 @@ android_library { "SystemUISharedLib", "SystemUI-statsd", "SettingsLib", + "androidx.core_core-ktx", "androidx.viewpager2_viewpager2", "androidx.legacy_legacy-support-v4", "androidx.recyclerview_recyclerview", diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING index 3bd6d51eecc6..f9a9ef65cab6 100644 --- a/packages/SystemUI/TEST_MAPPING +++ b/packages/SystemUI/TEST_MAPPING @@ -52,6 +52,17 @@ ] }, { + "name": "SystemUIGoogleScreenshotTests", + "options": [ + { + "exclude-annotation": "org.junit.Ignore" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, + { // Permission indicators "name": "CtsPermission4TestCases", "options": [ diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 5b47ae525919..fbe33565f11d 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -656,7 +656,7 @@ class ActivityLaunchAnimator( controller.onLaunchAnimationCancelled() } - override fun onAnimationCancelled() { + override fun onAnimationCancelled(isKeyguardOccluded: Boolean) { if (timedOut) { return } diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml index 0e20fa3f46b5..9c49607d414e 100644 --- a/packages/SystemUI/res/layout/media_session_view.xml +++ b/packages/SystemUI/res/layout/media_session_view.xml @@ -42,7 +42,6 @@ android:adjustViewBounds="true" android:clipToOutline="true" android:background="@drawable/qs_media_outline_album_bg" - android:foreground="@drawable/qs_media_scrim" /> <!-- Guideline for output switcher --> diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml index 5e8b892018eb..e079fd3c5e8f 100644 --- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml +++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml @@ -14,20 +14,25 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<!-- TODO(b/203800646): layout_marginTop doesn't seem to work on some large screens. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/media_ttt_receiver_chip" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@drawable/media_ttt_chip_background_receiver" > + <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView + android:id="@+id/ripple" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + <com.android.internal.widget.CachingIconView android:id="@+id/app_icon" android:layout_width="@dimen/media_ttt_icon_size_receiver" android:layout_height="@dimen/media_ttt_icon_size_receiver" - android:layout_gravity="center" + android:layout_gravity="center|bottom" + android:alpha="0.0" /> </FrameLayout> diff --git a/packages/SystemUI/res/layout/wireless_charging_layout.xml b/packages/SystemUI/res/layout/wireless_charging_layout.xml index 1312b413f106..887e3e715369 100644 --- a/packages/SystemUI/res/layout/wireless_charging_layout.xml +++ b/packages/SystemUI/res/layout/wireless_charging_layout.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <com.android.systemui.statusbar.charging.ChargingRippleView + <com.android.systemui.ripple.RippleView android:id="@+id/wireless_charging_ripple" android:layout_width="match_parent" android:layout_height="match_parent"/> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 5b2edbc060bb..f772e75bf653 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Toestel is gesluit"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skandeer tans gesig"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Stuur"</string> - <string name="phone_label" msgid="5715229948920451352">"maak foon oop"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"maak stembystand oop"</string> - <string name="camera_label" msgid="8253821920931143699">"maak kamera oop"</string> <string name="cancel" msgid="1089011503403416730">"Kanselleer"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestig"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probeer weer"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Verander uitvoer"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE. d MMM."</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 7214ec792749..b3f5d39a3101 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"የቅኝት ፊት"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ላክ"</string> - <string name="phone_label" msgid="5715229948920451352">"ስልክ ክፈት"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"የድምጽ ረዳትን ክፈት"</string> - <string name="camera_label" msgid="8253821920931143699">"ካሜራ ክፈት"</string> <string name="cancel" msgid="1089011503403416730">"ይቅር"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"አረጋግጥ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"እንደገና ይሞክሩ"</string> @@ -547,7 +544,7 @@ <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ግራ"</string> <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ቀኝ"</string> <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"መሃል"</string> - <string name="keyboard_key_tab" msgid="4592772350906496730">"ትር"</string> + <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string> <string name="keyboard_key_space" msgid="6980847564173394012">"ክፍተት"</string> <string name="keyboard_key_enter" msgid="8633362970109751646">"አስገባ"</string> <string name="keyboard_key_backspace" msgid="4095278312039628074">"የኋሊት መደምሰሻ"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ውፅዓትን ይቀይሩ"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ያልታወቀ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE፣ MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 3138bf966427..5bc1f89a9a86 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"الجهاز مُقفل."</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"إرسال"</string> - <string name="phone_label" msgid="5715229948920451352">"فتح الهاتف"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"فتح المساعد الصوتي"</string> - <string name="camera_label" msgid="8253821920931143699">"فتح الكاميرا"</string> <string name="cancel" msgid="1089011503403416730">"إلغاء"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأكيد"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"إعادة المحاولة"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغيير جهاز الإخراج"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"غير معروف"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE، d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index fdb27ff739e1..f411b7d9e533 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইচটো লক হৈ আছে"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"চেহেৰা স্কেন কৰি থকা হৈছে"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পঠিয়াওক"</string> - <string name="phone_label" msgid="5715229948920451352">"ফ\'ন খোলক"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"কণ্ঠধ্বনিৰে সহায় খোলক"</string> - <string name="camera_label" msgid="8253821920931143699">"কেমেৰা খোলক"</string> <string name="cancel" msgid="1089011503403416730">"বাতিল কৰক"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"নিশ্চিত কৰক"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আকৌ চেষ্টা কৰক"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট সলনি কৰক"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজ্ঞাত"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index e747282b2e35..fe542c1a79b4 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilidlənib"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Üzün skan edilməsi"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Göndərin"</string> - <string name="phone_label" msgid="5715229948920451352">"telefonu açın"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"səs yardımçısını açın"</string> - <string name="camera_label" msgid="8253821920931143699">"kemaranı açın"</string> <string name="cancel" msgid="1089011503403416730">"Ləğv edin"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Təsdiq"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yenidən cəhd edin"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Nəticəni dəyişdirin"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Naməlum"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"HHH, AAA g"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 2b6bd9a8c807..873663bc0e59 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string> - <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string> - <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string> <string name="cancel" msgid="1089011503403416730">"Otkaži"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index f7fabb7fef34..7e595c951054 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Прылада заблакіравана"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканіраванне твару"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Адправіць"</string> - <string name="phone_label" msgid="5715229948920451352">"адкрыць тэлефон"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"адкрыць галасавую дапамогу"</string> - <string name="camera_label" msgid="8253821920931143699">"адкрыць камеру"</string> <string name="cancel" msgid="1089011503403416730">"Скасаваць"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Пацвердзіць"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Паўтарыць спробу"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз сеткі VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змяненне вываду"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невядома"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index e6608f3cf489..d32b85a8623c 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Изпращане"</string> - <string name="phone_label" msgid="5715229948920451352">"отваряне на телефона"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"отваряне на гласовата помощ"</string> - <string name="camera_label" msgid="8253821920931143699">"отваряне на камерата"</string> <string name="cancel" msgid="1089011503403416730">"Отказ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потвърждаване"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Нов опит"</string> @@ -278,8 +275,8 @@ <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Включване, когато стане време за сън"</string> <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"До края на времето за сън"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> - <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string> - <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string> + <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е деактивирана"</string> + <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е активирана"</string> <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Запис на екрана"</string> <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Старт"</string> <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Стоп"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промяна на изхода"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 8a8949182055..7b5a7d88d42f 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইস লক করা আছে"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ফেস স্ক্যান করা হচ্ছে"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পাঠান"</string> - <string name="phone_label" msgid="5715229948920451352">"ফোন খুলুন"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ভয়েস সহায়তা খুলুন"</string> - <string name="camera_label" msgid="8253821920931143699">"ক্যামেরা খুলুন"</string> <string name="cancel" msgid="1089011503403416730">"বাতিল করুন"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"কনফার্ম করুন"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আবার চেষ্টা করুন"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট পরিবর্তন করুন"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজানা"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index ad7f10b5657f..c1d20e3a66b2 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string> - <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string> - <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string> <string name="cancel" msgid="1089011503403416730">"Otkaži"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdite"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string> @@ -374,11 +371,11 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet putem VPN-ova"</string> - <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem VPN-ova"</string> + <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem VPN-ova"</string> + <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem VPN-ova"</string> <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može pratiti mrežni saobraćaj na vašem profilu."</string> <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni saobraćaj na vašem radnom profilu"</string> <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Mrežna aktivnost radnog profila je vidljiva vašem IT administratoru"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promijeni izlaz"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index f7441f34073a..137b04733c07 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositiu bloquejat"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"S\'està escanejant la cara"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envia"</string> - <string name="phone_label" msgid="5715229948920451352">"obre el telèfon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"obre l\'assistència per veu"</string> - <string name="camera_label" msgid="8253821920931143699">"obre la càmera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel·la"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirma"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Torna-ho a provar"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Canvia la sortida"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconeguda"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index bb2ec59f5901..e0fa698f85aa 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Zařízení uzamčeno"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenování obličeje"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odeslat"</string> - <string name="phone_label" msgid="5715229948920451352">"otevřít telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otevřít hlasovou asistenci"</string> - <string name="camera_label" msgid="8253821920931143699">"spustit fotoaparát"</string> <string name="cancel" msgid="1089011503403416730">"Zrušit"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdit"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zkusit znovu"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zařízení poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu pomocí aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím sítí VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Změna výstupu"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznámé"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index c9722eb6635b..c52fc71c79d4 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheden er låst"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanner ansigt"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"åbn telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"åbn taleassistent"</string> - <string name="camera_label" msgid="8253821920931143699">"åbn kamera"</string> <string name="cancel" msgid="1089011503403416730">"Annuller"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekræft"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv igen"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via VPN-forbindelser"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skift output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukendt"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 169e475ddc49..815b231307f0 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Gerät gesperrt"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gesicht wird gescannt"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senden"</string> - <string name="phone_label" msgid="5715229948920451352">"Telefon öffnen"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"Sprachassistent öffnen"</string> - <string name="camera_label" msgid="8253821920931143699">"Kamera öffnen"</string> <string name="cancel" msgid="1089011503403416730">"Abbrechen"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bestätigen"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Noch einmal versuchen"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ausgabe ändern"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unbekannt"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index fc03b5737d3a..225f7ec20d47 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Η συσκευή κλειδώθηκε"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Σάρωση προσώπου"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Αποστολή"</string> - <string name="phone_label" msgid="5715229948920451352">"άνοιγμα τηλεφώνου"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"άνοιγμα φωνητικής υποβοήθησης"</string> - <string name="camera_label" msgid="8253821920931143699">"άνοιγμα φωτογραφικής μηχανής"</string> <string name="cancel" msgid="1089011503403416730">"Ακύρωση"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Επιβεβαίωση"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Δοκιμάστε ξανά"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει σε <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Αλλαγή εξόδου"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Άγνωστο"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ΗΗΗ, ΜΜΜ η"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 89b00b4d90bc..ccb0a284b2b2 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"open phone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"open camera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 0519c96dd306..4b14e1f68ca6 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"open phone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"open camera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 89b00b4d90bc..ccb0a284b2b2 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"open phone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"open camera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 89b00b4d90bc..ccb0a284b2b2 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"open phone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"open camera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index a341d5948029..4418230539bd 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"open phone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"open camera"</string> <string name="cancel" msgid="1089011503403416730">"Cancel"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index c759542bdc66..8140bda8fd4d 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando rostro"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Volver a intentarlo"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia la salida"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index aff899870990..955bb116865e 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando cara"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reintentar"</string> @@ -402,7 +399,7 @@ <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Se ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"El administrador ha activado el registro de la red para supervisar el tráfico en tu dispositivo."</string> <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Tu administrador ha activado el registro de la red, por lo que se monitorizará el tráfico de tu perfil de trabajo, aunque no el de tu perfil personal."</string> - <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string> + <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad en esta red, como tus correos electrónicos y tus datos de navegación, es visible para tu administrador de TI."</string> <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> y <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Tus aplicaciones de trabajo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red en las aplicaciones de trabajo, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI y tu proveedor de VPN."</string> <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Tus aplicaciones personales están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu proveedor de VPN."</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar salida"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml index d3e7c8b762de..8d5c3c6bcb6d 100644 --- a/packages/SystemUI/res/values-es/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml @@ -59,7 +59,7 @@ <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"No disponible"</item> <item msgid="5044688398303285224">"Desactivada"</item> - <item msgid="8527389108867454098">"Activada"</item> + <item msgid="8527389108867454098">"Activado"</item> </string-array> <string-array name="tile_states_rotation"> <item msgid="4578491772376121579">"No disponible"</item> @@ -88,7 +88,7 @@ </string-array> <string-array name="tile_states_color_correction"> <item msgid="2840507878437297682">"No disponible"</item> - <item msgid="1909756493418256167">"Desactivada"</item> + <item msgid="1909756493418256167">"Desactivado"</item> <item msgid="4531508423703413340">"Activado"</item> </string-array> <string-array name="tile_states_inversion"> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index e11a16597dd2..61ca78df4945 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Näo skannimine"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Saada"</string> - <string name="phone_label" msgid="5715229948920451352">"ava telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ava häälabi"</string> - <string name="camera_label" msgid="8253821920931143699">"ava kaamera"</string> <string name="cancel" msgid="1089011503403416730">"Tühista"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kinnita"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Proovi uuesti"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Väljundi muutmine"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tundmatu"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 35142b95f215..3b051e52d105 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Gailua blokeatuta dago"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Aurpegia eskaneatzen"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Bidali"</string> - <string name="phone_label" msgid="5715229948920451352">"ireki telefonoan"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ireki ahots-laguntza"</string> - <string name="camera_label" msgid="8253821920931143699">"ireki kamera"</string> <string name="cancel" msgid="1089011503403416730">"Utzi"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Berretsi"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Saiatu berriro"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Aldatu audio-irteera"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 8719b00b17c1..03191a866262 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ارسال"</string> - <string name="phone_label" msgid="5715229948920451352">"باز کردن تلفن"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"«دستیار صوتی» را باز کنید"</string> - <string name="camera_label" msgid="8253821920931143699">"باز کردن دوربین"</string> <string name="cancel" msgid="1089011503403416730">"لغو"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأیید"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"امتحان مجدد"</string> @@ -293,9 +290,9 @@ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"میکروفن مسدود شده است"</string> <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"دوربین مسدود شده است"</string> <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"میکروفون و دوربین مسدود شدهاند"</string> - <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریمخصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریمخصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> - <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریمخصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریمخصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> - <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریمخصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریمخصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> + <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> + <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> + <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریم خصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string> <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"میکروفون دردسترس است"</string> <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"دوربین دردسترس است"</string> <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"میکروفون و دوربین دردسترساند"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"همهفرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغییر خروجی"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامشخص"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 54be04f04aed..ba9f9afc6e9c 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Laite lukittu"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Kasvojen skannaus"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Lähetä"</string> - <string name="phone_label" msgid="5715229948920451352">"avaa puhelin"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"Avaa ääniapuri"</string> - <string name="camera_label" msgid="8253821920931143699">"avaa kamera"</string> <string name="cancel" msgid="1089011503403416730">"Peru"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Vahvista"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yritä uudelleen"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Muuta ulostuloa"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tuntematon"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"VKP, KKK p"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index f9b18962a157..eb2081071de9 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string> - <string name="phone_label" msgid="5715229948920451352">"Ouvrir le téléphone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string> - <string name="camera_label" msgid="8253821920931143699">"Ouvrir l\'appareil photo"</string> <string name="cancel" msgid="1089011503403416730">"Annuler"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de RPV"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Changer la sortie"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 815f0189dd01..1c6943f9a207 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analyse du visage en cours"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string> - <string name="phone_label" msgid="5715229948920451352">"ouvrir le téléphone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string> - <string name="camera_label" msgid="8253821920931143699">"ouvrir l\'appareil photo"</string> <string name="cancel" msgid="1089011503403416730">"Annuler"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Modifier le résultat"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM j"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index d510b83b90d8..9258be9a5d8c 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analizando cara"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir asistente de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar de novo"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar de saída"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Descoñecida"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 6d14e4621098..f3cc2dd7eaff 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"મોકલો"</string> - <string name="phone_label" msgid="5715229948920451352">"ફોન ખોલો"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"વૉઇસ સહાય ખોલો"</string> - <string name="camera_label" msgid="8253821920931143699">"કૅમેરા ખોલો"</string> <string name="cancel" msgid="1089011503403416730">"રદ કરો"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"કન્ફર્મ કરો"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ફરી પ્રયાસ કરો"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"આઉટપુટ બદલો"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"અજાણ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index d385337a1a44..15612080da5c 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"डिवाइस लॉक है"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"डिवाइस अनलॉक करने के लिए चेहरा स्कैन किया जाता है"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"भेजें"</string> - <string name="phone_label" msgid="5715229948920451352">"फ़ोन खोलें"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"आवाज़ से डिवाइस को इस्तेमाल करें"</string> - <string name="camera_label" msgid="8253821920931143699">"कैमरा खोलें"</string> <string name="cancel" msgid="1089011503403416730">"रद्द करें"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि करें"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फिर से कोशिश करें"</string> @@ -953,4 +950,10 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string> + <!-- no translation found for dream_date_complication_date_format (8191225366513860104) --> + <skip /> + <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) --> + <skip /> + <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 60a84029b4f1..01ad02b69356 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string> - <string name="phone_label" msgid="5715229948920451352">"otvaranje telefona"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otvaranje glasovne pomoći"</string> - <string name="camera_label" msgid="8253821920931143699">"otvaranje fotoaparata"</string> <string name="cancel" msgid="1089011503403416730">"Odustani"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promjena izlaza"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE., d. MMM."</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 9b09cccc1662..8d33bc8f4c56 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Az eszköz zárolva van"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Arc keresése"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Küldés"</string> - <string name="phone_label" msgid="5715229948920451352">"telefon megnyitása"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"hangsegéd megnyitása"</string> - <string name="camera_label" msgid="8253821920931143699">"kamera megnyitása"</string> <string name="cancel" msgid="1089011503403416730">"Mégse"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Megerősítés"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Újrapróbálkozás"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Kimenet módosítása"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ismeretlen"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, HHH n"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index a707c63d2bee..c69ee42cd85f 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Սարքը կողպված է"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Դեմքի սկանավորում"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ուղարկել"</string> - <string name="phone_label" msgid="5715229948920451352">"բացել հեռախոսը"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"բացեք ձայնային հուշումը"</string> - <string name="camera_label" msgid="8253821920931143699">"բացել ֆոտոխցիկը"</string> <string name="cancel" msgid="1089011503403416730">"Չեղարկել"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Հաստատել"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Նորից փորձել"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Փոխել աուդիո ելքը"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Անհայտ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index fb51e6bf8f32..19b9d40e84fe 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Perangkat terkunci"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Memindai wajah"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Kirim"</string> - <string name="phone_label" msgid="5715229948920451352">"buka ponsel"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string> - <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string> <string name="cancel" msgid="1089011503403416730">"Batal"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmasi"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Coba lagi"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ubah output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 7420ff18d7a0..93ed60375bbd 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Tækið er læst"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Andlit skannað"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senda"</string> - <string name="phone_label" msgid="5715229948920451352">"opna síma"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"opna raddaðstoð"</string> - <string name="camera_label" msgid="8253821920931143699">"opna myndavél"</string> <string name="cancel" msgid="1089011503403416730">"Hætta við"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Staðfesta"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reyna aftur"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skipta um úttak"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Óþekkt"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index e16fc15ec3d1..02917338874e 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloccato"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scansione del viso"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Invia"</string> - <string name="phone_label" msgid="5715229948920451352">"apri telefono"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"apri Voice Assist"</string> - <string name="camera_label" msgid="8253821920931143699">"apri fotocamera"</string> <string name="cancel" msgid="1089011503403416730">"Annulla"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Conferma"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Riprova"</string> @@ -953,4 +950,10 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string> + <!-- no translation found for dream_date_complication_date_format (8191225366513860104) --> + <skip /> + <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) --> + <skip /> + <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index a889c9cb552a..6a0199c66e3c 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"המכשיר נעול"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string> - <string name="phone_label" msgid="5715229948920451352">"פתיחת הטלפון"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"פתיחת האסיסטנט"</string> - <string name="camera_label" msgid="8253821920931143699">"פתיחת המצלמה"</string> <string name="cancel" msgid="1089011503403416730">"ביטול"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"שינוי הפלט"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"לא ידוע"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"יום EEE, d בMMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 7bfa60cc3e56..3a34f3c2206e 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"デバイスはロックされています"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"顔のスキャン"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"送信"</string> - <string name="phone_label" msgid="5715229948920451352">"電話を起動"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"音声アシストを開く"</string> - <string name="camera_label" msgid="8253821920931143699">"カメラを起動"</string> <string name="cancel" msgid="1089011503403416730">"キャンセル"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試行"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g>を介してインターネットに接続しています"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有し、<xliff:g id="VPN_APP">%2$s</xliff:g> を介してインターネットに接続されています"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"これは組織が所有するデバイスで、VPN を介してインターネットに接続しています"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"出力を変更"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 406aea64e618..57b56f7b57e7 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"მოწყობილობა ჩაკეტილია"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"მიმდინარეობს სახის სკანირება"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"გაგზავნა"</string> - <string name="phone_label" msgid="5715229948920451352">"ტელეფონის გახსნა"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ხმოვანი დახმარების გახსნა"</string> - <string name="camera_label" msgid="8253821920931143699">"კამერის გახსნა"</string> <string name="cancel" msgid="1089011503403416730">"გაუქმება"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"დადასტურება"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ხელახლა ცდა"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"აუდიოს გამოსასვლელის შეცვლა"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"უცნობი"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"დდდ, თთთ თ"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 4f5b7e05cf48..e14c8274d125 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Құрылғы құлыпталды."</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Бетті сканерлеу"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string> - <string name="phone_label" msgid="5715229948920451352">"телефонды ашу"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ашық дауыс көмекшісі"</string> - <string name="camera_label" msgid="8253821920931143699">"камераны ашу"</string> <string name="cancel" msgid="1089011503403416730">"Бас тарту"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Растау"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайталап көріңіз"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудио шығысын өзгерту"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгісіз"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index a921cb94b7e2..14fa8de52289 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"បានចាក់សោឧបករណ៍"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ការស្កេនមុខ"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ផ្ញើ"</string> - <string name="phone_label" msgid="5715229948920451352">"បើកទូរស័ព្ទ"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"បើកជំនួយសំឡេង"</string> - <string name="camera_label" msgid="8253821920931143699">"បើកម៉ាស៊ីនថត"</string> <string name="cancel" msgid="1089011503403416730">"បោះបង់"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"បញ្ជាក់"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ព្យាយាមម្ដងទៀត"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"មិនស្គាល់"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 46fa9a4c4d7e..f980937cca84 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ಕಳುಹಿಸಿ"</string> - <string name="phone_label" msgid="5715229948920451352">"ಫೋನ್ ತೆರೆಯಿರಿ"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string> - <string name="camera_label" msgid="8253821920931143699">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string> <string name="cancel" msgid="1089011503403416730">"ರದ್ದುಮಾಡಿ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ದೃಢೀಕರಿಸಿ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ಔಟ್ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 47c26460b94e..cd88795f771b 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"기기 잠김"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"얼굴 스캔 중"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"보내기"</string> - <string name="phone_label" msgid="5715229948920451352">"휴대전화 열기"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"음성 지원 열기"</string> - <string name="camera_label" msgid="8253821920931143699">"카메라 열기"</string> <string name="cancel" msgid="1089011503403416730">"취소"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"확인"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"다시 시도하세요."</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"출력 변경"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"알 수 없음"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d일 EEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 437708acefff..391311159d34 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -50,7 +50,7 @@ <string name="usb_debugging_title" msgid="8274884945238642726">"USB аркылуу жөндөөгө уруксат берилсинби?"</string> <string name="usb_debugging_message" msgid="5794616114463921773">"Компүтердин RSA ачкычынын контролдук суммасы:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string> <string name="usb_debugging_always" msgid="4003121804294739548">"Бул компүтерден дайыма уруксат берилсин"</string> - <string name="usb_debugging_allow" msgid="1722643858015321328">"Уруксат берүү"</string> + <string name="usb_debugging_allow" msgid="1722643858015321328">"Ооба"</string> <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string> <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү аныктоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string> <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Тутум тилин <xliff:g id="LANGUAGE">%1$s</xliff:g> тилине өзгөртөсүзбү?"</string> @@ -60,7 +60,7 @@ <string name="wifi_debugging_title" msgid="7300007687492186076">"Ушул тармакта мүчүлүштүктөрдү Wi-Fi аркылуу аныктоого уруксат бересизби?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Тармактын аталышы (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi дареги (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Бул тармакта ар дайым уруксат берилсин"</string> - <string name="wifi_debugging_allow" msgid="4573224609684957886">"Уруксат берүү"</string> + <string name="wifi_debugging_allow" msgid="4573224609684957886">"Ооба"</string> <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилген жок"</string> <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Учурда бул түзмөккө кирген колдонуучу мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо функциясын күйгүзө албайт. Бул функцияны колдонуу үчүн негизги колдонуучунун аккаунтуна которулуңуз."</string> <string name="usb_contaminant_title" msgid="894052515034594113">"USB порту өчүрүлдү"</string> @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жөнөтүү"</string> - <string name="phone_label" msgid="5715229948920451352">"телефонду ачуу"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"үн жардамчысысын ачуу"</string> - <string name="camera_label" msgid="8253821920931143699">"камераны ачуу"</string> <string name="cancel" msgid="1089011503403416730">"Жок"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Ырастоо"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Кайталоо"</string> @@ -470,7 +467,7 @@ <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңырууда"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string> - <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Кулпуланган экран жөндөөлөрү"</string> + <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экранды кулпулоо параметрлери"</string> <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодун скандоо"</string> <string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string> <string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудионун чыгуусун өзгөртүү"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгисиз"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 8e84afec9689..469f77bf60d0 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ອຸປະກອນຖືກລັອກໄວ້"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ການສະແກນໜ້າ"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ສົ່ງ"</string> - <string name="phone_label" msgid="5715229948920451352">"ເປີດແປ້ນໂທລະສັບ"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ຊ່ວເຫຼືອເປີດສຽງ"</string> - <string name="camera_label" msgid="8253821920931143699">"ເປີດກ້ອງ"</string> <string name="cancel" msgid="1089011503403416730">"ຍົກເລີກ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ຢືນຢັນ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ລອງໃໝ່"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ປ່ຽນເອົ້າພຸດ"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ບໍ່ຮູ້ຈັກ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 372217629b04..66c9c3466f6a 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Nuskaitomas veidas"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Siųsti"</string> - <string name="phone_label" msgid="5715229948920451352">"atidaryti telefoną"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"atidaryti „Voice Assist“"</string> - <string name="camera_label" msgid="8253821920931143699">"atidaryti fotoaparatą"</string> <string name="cancel" msgid="1089011503403416730">"Atšaukti"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Patvirtinkite"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Bandyti dar kartą"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Keisti išvestį"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nežinoma"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a1a242450f73..a32c5e41be30 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Sūtīt"</string> - <string name="phone_label" msgid="5715229948920451352">"atvērt tālruni"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"atvērt balss palīgu"</string> - <string name="camera_label" msgid="8253821920931143699">"atvērt kameru"</string> <string name="cancel" msgid="1089011503403416730">"Atcelt"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Apstiprināt"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Mēģināt vēlreiz"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Izvades maiņa"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nezināms"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 5c1bf4afff13..d7951b190241 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Уредот е заклучен"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лице"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Испрати"</string> - <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовна помош"</string> - <string name="camera_label" msgid="8253821920931143699">"отвори камера"</string> <string name="cancel" msgid="1089011503403416730">"Откажи"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Обиди се повторно"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Променете излез"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index e95197891ead..5b0164d8e3be 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ഉപകരണം ലോക്ക് ചെയ്തു"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"മുഖം സ്കാൻ ചെയ്യുന്നു"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"അയയ്ക്കുക"</string> - <string name="phone_label" msgid="5715229948920451352">"ഫോൺ തുറക്കുക"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"വോയ്സ് അസിസ്റ്റ് തുറക്കുക"</string> - <string name="camera_label" msgid="8253821920931143699">"ക്യാമറ തുറക്കുക"</string> <string name="cancel" msgid="1089011503403416730">"റദ്ദാക്കുക"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"സ്ഥിരീകരിക്കുക"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"വീണ്ടും ശ്രമിക്കുക"</string> @@ -406,7 +403,7 @@ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ഈ ഉപകരണം <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നിവയിലൂടെ ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്മിന് ദൃശ്യമാകും."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള, ഔദ്യോഗിക ആപ്പുകളിലെ നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്മിനും VPN ദാതാവിനും ദൃശ്യമാകും."</string> <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ VPN ദാതാവിന് ദൃശ്യമാകും."</string> - <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" 5"</string> + <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ക്രമീകരണം തുറക്കുക"</string> <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാനും നിയന്ത്രിക്കാനുമാകും."</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുക"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ഔട്ട്പുട്ട് മാറ്റുക"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"അജ്ഞാതം"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index f9ca17eace54..2648c5c2477d 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Төхөөрөмжийг түгжсэн"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скан хийх нүүр царай"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Илгээх"</string> - <string name="phone_label" msgid="5715229948920451352">"утас нээх"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"дуут туслахыг нээнэ"</string> - <string name="camera_label" msgid="8253821920931143699">"камер нээх"</string> <string name="cancel" msgid="1089011503403416730">"Цуцлах"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Баталгаажуулах"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Дахин оролдох"</string> @@ -173,7 +170,7 @@ <string name="cell_data_off" msgid="4886198950247099526">"Идэвхгүй"</string> <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Нислэгийн горим"</string> <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN асаалттай байна."</string> - <string name="accessibility_battery_level" msgid="5143715405241138822">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string> + <string name="accessibility_battery_level" msgid="5143715405241138822">"Батарей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string> <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string> <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string> <string name="accessibility_overflow_action" msgid="8555835828182509104">"Бүх мэдэгдлийг харах"</string> @@ -214,7 +211,7 @@ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Бүү саад бол"</string> <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Хослуулсан төхөөрөмж байхгүй"</string> - <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерей"</string> + <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string> <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string> @@ -248,7 +245,7 @@ <string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Хаах"</string> <string name="quick_settings_connected" msgid="3873605509184830379">"Холбогдсон"</string> - <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="quick_settings_connecting" msgid="2381969772953268809">"Холбогдож байна..."</string> <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Сүлжээний цэг"</string> <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Асааж байна…"</string> @@ -706,7 +703,7 @@ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string> <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string> <string name="running_foreground_services_title" msgid="5137313173431186685">"Цаана ажиллаж буй апп"</string> - <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string> + <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string> <string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобайл датаг унтраах уу?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"Та <xliff:g id="CARRIER">%s</xliff:g>-р дата эсвэл интернэтэд хандах боломжгүй болно. Интернэтэд зөвхөн Wi-Fi-р холбогдох боломжтой болно."</string> <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"таны оператор компани"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Гаралтыг өөрчлөх"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Тодорхойгүй"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 19694dbea63e..7129762b6e58 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"डिव्हाइस लॉक केले"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"चेहरा स्कॅन करत आहे"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पाठवा"</string> - <string name="phone_label" msgid="5715229948920451352">"फोन उघडा"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"व्हॉइस सहाय्य उघडा"</string> - <string name="camera_label" msgid="8253821920931143699">"कॅमेरा उघडा"</string> <string name="cancel" msgid="1089011503403416730">"रद्द करा"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"कंफर्म करा"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"पुन्हा प्रयत्न करा"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपूट बदला"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index e85b3a01e8be..e37d88cd4f8a 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Peranti dikunci"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Mengimbas wajah"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Hantar"</string> - <string name="phone_label" msgid="5715229948920451352">"buka telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string> - <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string> <string name="cancel" msgid="1089011503403416730">"Batal"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Sahkan"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Cuba lagi"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Tukar output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 81f8189c00d6..301d42e2e3c3 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ပို့ရန်"</string> - <string name="phone_label" msgid="5715229948920451352">"ဖုန်းကို ဖွင့်ရန်"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"အသံ အကူအညီအား ဖွင့်ရန်"</string> - <string name="camera_label" msgid="8253821920931143699">"ကင်မရာ ဖွင့်ရန်"</string> <string name="cancel" msgid="1089011503403416730">"မလုပ်တော့"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"အတည်ပြုပါ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ထပ်စမ်းကြည့်ရန်"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"အထွက်ကို ပြောင်းခြင်း"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"မသိ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE၊ MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index d6ce3feb1a79..64bc528fc71f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten er låst"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanning av ansikt"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string> - <string name="phone_label" msgid="5715229948920451352">"åpne telefonen"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"åpne talehjelp"</string> - <string name="camera_label" msgid="8253821920931143699">"åpne kamera"</string> <string name="cancel" msgid="1089011503403416730">"Avbryt"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekreft"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv på nytt"</string> @@ -250,7 +247,7 @@ <string name="quick_settings_connected" msgid="3873605509184830379">"Tilkoblet"</string> <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="quick_settings_connecting" msgid="2381969772953268809">"Kobler til …"</string> - <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wi-Fi-sone"</string> + <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wifi-sone"</string> <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Slår på …"</string> <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datasparing er på"</string> <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhet}other{# enheter}}"</string> @@ -477,7 +474,7 @@ <string name="zen_alarm_warning" msgid="7844303238486849503">"Du hører ikke neste innstilte alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> - <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wi-Fi-sone"</string> + <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wifi-sone"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string> <string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string> @@ -912,7 +909,7 @@ <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi kobles ikke til automatisk inntil videre"</string> <string name="see_all_networks" msgid="3773666844913168122">"Se alle"</string> <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"For å bytte nettverk, koble fra Ethernet"</string> - <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for Wi-Fi-skanning. "<annotation id="link">"Endre"</annotation></string> + <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for wifi-skanning. "<annotation id="link">"Endre"</annotation></string> <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Slå av flymodus"</string> <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vil legge til denne brikken i Hurtiginnstillinger"</string> <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Legg til brikke"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Endre utgang"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukjent"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"t:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"tt:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 409db0b91e56..4db5278a170d 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पठाउनुहोस्"</string> - <string name="phone_label" msgid="5715229948920451352">"फोन खोल्नुहोस्"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"आवाज सहायता खोल्नुहोस्"</string> - <string name="camera_label" msgid="8253821920931143699">"क्यामेरा खोल्नुहोस्"</string> <string name="cancel" msgid="1089011503403416730">"रद्द गर्नुहोस्"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि गर्नुहोस्"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फेरि प्रयास गर्नुहोस्"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट परिवर्तन गर्नुहोस्"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 9501ddf1dedf..07c53c513c73 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Apparaat vergrendeld"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gezicht scannen"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Verzenden"</string> - <string name="phone_label" msgid="5715229948920451352">"telefoon openen"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"spraakassistent openen"</string> - <string name="camera_label" msgid="8253821920931143699">"camera openen"</string> <string name="cancel" msgid="1089011503403416730">"Annuleren"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestigen"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Opnieuw proberen"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft verbinding met internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft internetverbinding via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via VPN\'s"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Uitvoer wijzigen"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d mmm"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 681c2bb48b19..7eda9bc84dd3 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string> - <string name="phone_label" msgid="5715229948920451352">"ଫୋନ୍ ଖୋଲନ୍ତୁ"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ଭଏସ୍ ସହାୟକ ଖୋଲନ୍ତୁ"</string> - <string name="camera_label" msgid="8253821920931143699">"କ୍ୟାମେରା ଖୋଲନ୍ତୁ"</string> <string name="cancel" msgid="1089011503403416730">"ବାତିଲ୍ କରନ୍ତୁ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ଅଜଣା"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 0ca2cde2b9ef..425e66472b47 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ਚਿਹਰਾ ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ਭੇਜੋ"</string> - <string name="phone_label" msgid="5715229948920451352">"ਫ਼ੋਨ ਖੋਲ੍ਹੋ"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਖੋਲ੍ਹੋ"</string> - <string name="camera_label" msgid="8253821920931143699">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string> <string name="cancel" msgid="1089011503403416730">"ਰੱਦ ਕਰੋ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ਤਸਦੀਕ ਕਰੋ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ਅਗਿਆਤ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 0da22d55da3e..ccf51800d2ed 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Urządzenie zablokowane"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanowanie twarzy"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Wyślij"</string> - <string name="phone_label" msgid="5715229948920451352">"otwórz telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otwórz pomoc głosową"</string> - <string name="camera_label" msgid="8253821920931143699">"otwórz aparat"</string> <string name="cancel" msgid="1089011503403416730">"Anuluj"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potwierdź"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Spróbuj jeszcze raz"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmień dane wyjściowe"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Brak informacji"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index d166901ace8d..1fa4954ccb58 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 8c5369869806..7f24b90448f0 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"A analisar o rosto…"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir telemóvel"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistente de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir câmara"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Altere a saída"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecida"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index d166901ace8d..1fa4954ccb58 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string> - <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string> - <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string> <string name="cancel" msgid="1089011503403416730">"Cancelar"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 88f9963615c4..80cdb953b527 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispozitiv blocat"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanarea chipului"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Trimiteți"</string> - <string name="phone_label" msgid="5715229948920451352">"deschideți telefonul"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"deschideți asistentul vocal"</string> - <string name="camera_label" msgid="8253821920931143699">"deschideți camera foto"</string> <string name="cancel" msgid="1089011503403416730">"Anulați"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmați"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Încercați din nou"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%2$s</xliff:g>."</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și e conectat la internet prin <xliff:g id="VPN_APP">%2$s</xliff:g>."</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin rețele VPN."</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Schimbați rezultatul"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Necunoscută"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE, z LLL"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index fefdd81d3533..dd5e0e5a9561 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Устройство заблокировано"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканирование лица"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Отправить"</string> - <string name="phone_label" msgid="5715229948920451352">"Открыть телефон."</string> - <string name="voice_assist_label" msgid="3725967093735929020">"включить аудиоподсказки"</string> - <string name="camera_label" msgid="8253821920931143699">"Открыть камеру."</string> <string name="cancel" msgid="1089011503403416730">"Отмена"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Подтвердить"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторить попытку"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\"."</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Это устройство принадлежит вашей организации и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устр-во принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Это устройство принадлежит вашей организации и подключено к интернету через сети VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Транслировать на другое устройство"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 3c0d8392f829..b2c393f6c16d 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"උපාංගය අගුලු දමා ඇත"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"මුහුණ ස්කෑන් කිරීම"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"යවන්න"</string> - <string name="phone_label" msgid="5715229948920451352">"දුරකථනය විවෘත කරන්න"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"විවෘත හඬ සහාය"</string> - <string name="camera_label" msgid="8253821920931143699">"කැමරාව විවෘත කරන්න"</string> <string name="cancel" msgid="1089011503403416730">"අවලංගු කරන්න"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"තහවුරු කරන්න"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"නැවත උත්සාහ කරන්න"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ප්රතිදානය වෙනස් කරන්න"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"නොදනී"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index cbd4559b5e68..542f197cf429 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Zariadenie je uzamknuté"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenovanie tváre"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odoslať"</string> - <string name="phone_label" msgid="5715229948920451352">"otvoriť telefón"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"otvoriť hlasového asistenta"</string> - <string name="camera_label" msgid="8253821920931143699">"spustiť fotoaparát"</string> <string name="cancel" msgid="1089011503403416730">"Zrušiť"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdiť"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Skúsiť znova"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zariadenie poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené cez aplikáciu <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zariadenie patrí vašej organizácii"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom sietí VPN"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmena výstupu"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznáme"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index e723b1b10055..9dfc7cc3c618 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Naprava je zaklenjena."</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Optično branje obraza"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošlji"</string> - <string name="phone_label" msgid="5715229948920451352">"odpri telefon"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"odpri glasovnega pomočnika"</string> - <string name="camera_label" msgid="8253821920931143699">"odpri fotoaparat"</string> <string name="cancel" msgid="1089011503403416730">"Prekliči"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potrdite"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Poskusi znova"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Sprememba izhoda"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznano"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 4b19b367642a..8417ee640566 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Po skanon fytyrën"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Dërgo"</string> - <string name="phone_label" msgid="5715229948920451352">"hap telefonin"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"hap ndihmën zanore"</string> - <string name="camera_label" msgid="8253821920931143699">"hap kamerën"</string> <string name="cancel" msgid="1089011503403416730">"Anulo"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmo"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Provo përsëri"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ndrysho daljen"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"I panjohur"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 15d31bd073f0..3bb3bfb1124c 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string> - <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовну помоћ"</string> - <string name="camera_label" msgid="8253821920931143699">"отвори камеру"</string> <string name="cancel" msgid="1089011503403416730">"Откажи"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ДДД, д. МММ"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index effe9e539ed4..b7f9b05ad4b6 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten är låst"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Registrerar ansikte"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Skicka"</string> - <string name="phone_label" msgid="5715229948920451352">"öppna mobilen"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"öppna röstassistenten"</string> - <string name="camera_label" msgid="8253821920931143699">"öppna kameran"</string> <string name="cancel" msgid="1089011503403416730">"Avbryt"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekräfta"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Försök igen"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Byt ljudutgång"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Okänt"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 6c8e02f3de8e..1f5b7eac04c1 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Kifaa kimefungwa"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Inachanganua uso"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Tuma"</string> - <string name="phone_label" msgid="5715229948920451352">"fungua simu"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"fungua mapendekezo ya sauti"</string> - <string name="camera_label" msgid="8253821920931143699">"fungua kamera"</string> <string name="cancel" msgid="1089011503403416730">"Ghairi"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Thibitisha"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Jaribu tena"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Badilisha maudhui"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Haijulikani"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 36767ea2d407..8fea33e79de8 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"சாதனம் பூட்டப்பட்டுள்ளது"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string> - <string name="phone_label" msgid="5715229948920451352">"ஃபோனைத் திற"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"குரல் உதவியைத் திற"</string> - <string name="camera_label" msgid="8253821920931143699">"கேமராவைத் திற"</string> <string name="cancel" msgid="1089011503403416730">"ரத்துசெய்"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"உறுதிப்படுத்துக"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"மீண்டும் முயல்க"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"அவுட்புட்டை மாற்று"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"தெரியவில்லை"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 4d124f5ed6e7..759ebb471bb5 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"పరికరం లాక్ చేయబడింది"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ముఖాన్ని స్కాన్ చేస్తోంది"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"పంపు"</string> - <string name="phone_label" msgid="5715229948920451352">"ఫోన్ను తెరువు"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"వాయిస్ అసిస్టెంట్ను తెరువు"</string> - <string name="camera_label" msgid="8253821920931143699">"కెమెరాను తెరవండి"</string> <string name="cancel" msgid="1089011503403416730">"రద్దు చేయండి"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"నిర్ధారించు"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"మళ్లీ ప్రయత్నించు"</string> @@ -480,7 +477,7 @@ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"హాట్స్పాట్"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string> - <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్ఫేస్ను మెరుగుపరచడానికి మరియు అనుకూలీకరించడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> + <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్ఫేస్ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> <string name="tuner_persistent_warning" msgid="230466285569307806">"ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> <string name="got_it" msgid="477119182261892069">"అర్థమైంది"</string> <string name="tuner_toast" msgid="3812684836514766951">"అభినందనలు! సెట్టింగ్లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string> @@ -750,7 +747,7 @@ <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్ను మ్యాగ్నిఫై చేయండి"</string> <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్లో భాగాన్ని మాగ్నిఫై చేయండి"</string> <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string> - <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్లలో ఈ బటన్ను అనుకూలీకరించండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్లు"</annotation></string> + <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్లలో ఈ బటన్ను అనుకూలంగా మార్చండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్లు"</annotation></string> <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్ను చివరకు తరలించండి"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ఎగువ ఎడమ వైపునకు తరలించు"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ఎగువ కుడి వైపునకు తరలించు"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"అవుట్పుట్ను మార్చండి"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"తెలియదు"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 8daf4b58e747..99c2e32a6947 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"อุปกรณ์ถูกล็อก"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"กำลังสแกนใบหน้า"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ส่ง"</string> - <string name="phone_label" msgid="5715229948920451352">"เปิดโทรศัพท์"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"เปิดตัวช่วยเสียง"</string> - <string name="camera_label" msgid="8253821920931143699">"เปิดกล้อง"</string> <string name="cancel" msgid="1089011503403416730">"ยกเลิก"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ยืนยัน"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ลองอีกครั้ง"</string> @@ -915,12 +912,12 @@ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยนการตั้งค่า"</annotation></string> <string name="turn_off_airplane_mode" msgid="8425587763226548579">"ปิดโหมดบนเครื่องบิน"</string> <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มองค์ประกอบต่อไปนี้ในการตั้งค่าด่วน"</string> - <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มชิ้นส่วน"</string> - <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่ต้องเพิ่มชิ้นส่วน"</string> + <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มองค์ประกอบ"</string> + <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่เพิ่มองค์ประกอบ"</string> <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"เลือกผู้ใช้"</string> <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{ทำงานอยู่ # แอป}other{ทำงานอยู่ # แอป}}"</string> <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string> - <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string> + <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ทำงานอยู่"</string> <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"แอปเหล่านี้กำลังทำงานแม้ว่าคุณจะไม่ได้ใช้งานอยู่ก็ตาม วิธีนี้ช่วยให้ฟังก์ชันการทำงานของแอปมีประสิทธิภาพมากขึ้น แต่ก็อาจส่งผลต่ออายุการใช้งานแบตเตอรี่ด้วย"</string> <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string> <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"เปลี่ยนเอาต์พุต"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ไม่ทราบ"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index e8c191b91633..2943313eb071 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Naka-lock ang device"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sina-scan ang mukha"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ipadala"</string> - <string name="phone_label" msgid="5715229948920451352">"buksan ang telepono"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"buksan ang voice assist"</string> - <string name="camera_label" msgid="8253821920931143699">"buksan ang camera"</string> <string name="cancel" msgid="1089011503403416730">"Kanselahin"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kumpirmahin"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Subukang muli"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Baguhin ang output"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Hindi alam"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index adb3fb4c40a5..00569a0b5f5c 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilitlendi"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yüz taranıyor"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gönder"</string> - <string name="phone_label" msgid="5715229948920451352">"telefonu aç"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"sesli yardımı aç"</string> - <string name="camera_label" msgid="8253821920931143699">"kamerayı aç"</string> <string name="cancel" msgid="1089011503403416730">"İptal"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Onayla"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tekrar dene"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Çıkışı değiştirme"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Bilinmiyor"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM, EEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 66fb209fb9df..85573a925293 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Пристрій заблоковано"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканування обличчя"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Надіслати"</string> - <string name="phone_label" msgid="5715229948920451352">"відкрити телефон"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"запустити голосові підказки"</string> - <string name="camera_label" msgid="8253821920931143699">"відкрити камеру"</string> <string name="cancel" msgid="1089011503403416730">"Скасувати"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Підтвердити"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторити спробу"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змінити аудіовихід"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невідомо"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index c40927e28208..d9d1cbd12fb3 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"بھیجیں"</string> - <string name="phone_label" msgid="5715229948920451352">"فون کھولیں"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"صوتی معاون کھولیں"</string> - <string name="camera_label" msgid="8253821920931143699">"کیمرا کھولیں"</string> <string name="cancel" msgid="1089011503403416730">"منسوخ کريں"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تصدیق کریں"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"دوبارہ کوشش کریں"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"آؤٹ پٹ تبدیل کریں"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامعلوم"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index f9ad0b73e700..65a3e5113902 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Qurilma qulflandi"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yuzni skanerlash"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Yuborish"</string> - <string name="phone_label" msgid="5715229948920451352">"telefonni ochish"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"ovozli yordamni yoqish"</string> - <string name="camera_label" msgid="8253821920931143699">"kamerani ochish"</string> <string name="cancel" msgid="1089011503403416730">"Bekor qilish"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"OK"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Qayta urinish"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ovoz chiqishini oʻzgartirish"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Noaniq"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 7df433910076..7340db2fe58d 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Đã khóa thiết bị"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Quét tìm khuôn mặt"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gửi"</string> - <string name="phone_label" msgid="5715229948920451352">"mở điện thoại"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"mở trợ lý thoại"</string> - <string name="camera_label" msgid="8253821920931143699">"mở máy ảnh"</string> <string name="cancel" msgid="1089011503403416730">"Hủy"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Xác nhận"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Thử lại"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Thay đổi đầu ra"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Không xác định"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 62b1bd87bca5..96d895832bfe 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"设备已锁定"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"正在扫描面孔"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"发送"</string> - <string name="phone_label" msgid="5715229948920451352">"打开电话"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"打开语音助理"</string> - <string name="camera_label" msgid="8253821920931143699">"打开相机"</string> <string name="cancel" msgid="1089011503403416730">"取消"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"确认"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"重试"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"更改输出来源"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"未知"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 2ac494a20db5..89c7c29e4494 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已上鎖"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃瞄緊面孔"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string> - <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音助手"</string> - <string name="camera_label" msgid="8253821920931143699">"開啟相機"</string> <string name="cancel" msgid="1089011503403416730">"取消"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"請再試一次"</string> @@ -374,7 +371,7 @@ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string> <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於您的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string> - <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string> + <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所有,並透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string> <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於您的機構,並已透過 VPN 連接至互聯網"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index a0fe941eb5a6..9e22840d6478 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已鎖定"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃描臉孔"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string> - <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音小幫手"</string> - <string name="camera_label" msgid="8253821920931143699">"開啟攝影機"</string> <string name="cancel" msgid="1089011503403416730">"取消"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試一次"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 47de98eadb9a..a6e302664728 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -124,9 +124,6 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"Idivayisi ikhiyiwe"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"Ukuskena ubuso"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Thumela"</string> - <string name="phone_label" msgid="5715229948920451352">"vula ifoni"</string> - <string name="voice_assist_label" msgid="3725967093735929020">"vula isilekeleli sezwi"</string> - <string name="camera_label" msgid="8253821920931143699">"vula ikhamera"</string> <string name="cancel" msgid="1089011503403416730">"Khansela"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Qinisekisa"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zama futhi"</string> @@ -953,4 +950,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Shintsha okuphumayo"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Akwaziwa"</string> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 7f7b8716d27c..bb5c5928181a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1057,6 +1057,7 @@ <!-- Since the generic icon isn't circular, we need to scale it down so it still fits within the circular chip. --> <dimen name="media_ttt_generic_icon_size_receiver">70dp</dimen> + <dimen name="media_ttt_receiver_vert_translation">20dp</dimen> <!-- Window magnification --> <dimen name="magnification_border_drag_size">35dp</dimen> diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt index 363ce10fa36c..564901c2a773 100644 --- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt +++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt @@ -20,6 +20,7 @@ import android.app.UiModeManager import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas +import android.os.Build import android.os.UserHandle import android.view.Display import android.view.View @@ -32,6 +33,7 @@ import platform.test.screenshot.GoldenImagePathManager import platform.test.screenshot.PathConfig import platform.test.screenshot.PathElementNoContext import platform.test.screenshot.ScreenshotTestRule +import platform.test.screenshot.matchers.MSSIMMatcher import platform.test.screenshot.matchers.PixelPerfectMatcher /** @@ -55,7 +57,11 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { currentDisplay?.name ?: error("currentDisplay is null") }, ) - private val defaultMatcher = PixelPerfectMatcher() + private val matcher = if (shouldUsePerfectMatching()) { + PixelPerfectMatcher() + } else { + MSSIMMatcher() + } private val screenshotRule = ScreenshotTestRule( @@ -67,6 +73,17 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { ) ) + private fun shouldUsePerfectMatching(): Boolean { + // Different CPU architectures can sometimes end up rendering differently, so we can't do + // pixel-perfect matching on different architectures using the same golden. Given that our + // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the + // x86_64 architecture and use the Structural Similarity Index on others. + // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can + // do pixel perfect matching both at presubmit time and at development time with actual + // devices. + return Build.CPU_ABI == "x86_64" + } + override fun apply(base: Statement, description: Description): Statement { // The statement which call beforeTest() before running the test and afterTest() afterwards. val statement = @@ -147,7 +164,7 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { // device to assertBitmapAgainstGolden instead? currentDisplay = testSpec.display currentGoldenIdentifier = goldenIdentifier - screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, defaultMatcher) + screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, matcher) currentDisplay = null currentGoldenIdentifier = goldenIdentifier } diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt index 2c3ff2c75c72..6a80c486d515 100644 --- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt +++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt @@ -1,6 +1,7 @@ package com.android.systemui.testing.screenshot import android.app.Activity +import android.app.Dialog import android.view.View import android.view.ViewGroup import android.view.ViewGroup.LayoutParams @@ -23,20 +24,20 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule { } /** - * Compare the content of [view] with the golden image identified by [goldenIdentifier] in the - * context of [testSpec]. + * Compare the content of the view provided by [viewProvider] with the golden image identified + * by [goldenIdentifier] in the context of [testSpec]. */ fun screenshotTest( goldenIdentifier: String, layoutParams: LayoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT), - view: (Activity) -> View, + viewProvider: (Activity) -> View, ) { activityRule.scenario.onActivity { activity -> // Make sure that the activity draws full screen and fits the whole display instead of // the system bars. activity.window.setDecorFitsSystemWindows(false) - activity.setContentView(view(activity), layoutParams) + activity.setContentView(viewProvider(activity), layoutParams) } // We call onActivity again because it will make sure that our Activity is done measuring, @@ -48,4 +49,42 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule { screenshotRule.screenshotTest(goldenIdentifier, content.getChildAt(0)) } } + + /** + * Compare the content of the dialog provided by [dialogProvider] with the golden image + * identified by [goldenIdentifier] in the context of [testSpec]. + */ + fun dialogScreenshotTest( + goldenIdentifier: String, + dialogProvider: (Activity) -> Dialog, + ) { + var dialog: Dialog? = null + activityRule.scenario.onActivity { activity -> + dialog = + dialogProvider(activity).apply { + // Make sure that the dialog draws full screen and fits the whole display + // instead of the system bars. + window.setDecorFitsSystemWindows(false) + + // Disable enter/exit animations. + create() + window.setWindowAnimations(0) + + // Show the dialog. + show() + } + } + + // We call onActivity again because it will make sure that our Dialog is done measuring, + // laying out and drawing its content (that we set in the previous onActivity lambda). + activityRule.scenario.onActivity { + // Check that the content is what we expected. + val dialog = dialog ?: error("dialog is null") + try { + screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView) + } finally { + dialog.dismiss() + } + } + } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java index 88fe03465405..203b236fcdd6 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java @@ -80,7 +80,8 @@ public class PipSurfaceTransactionHelper { public PictureInPictureSurfaceTransaction scaleAndCrop( SurfaceControl.Transaction tx, SurfaceControl leash, - Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets) { + Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets, + float progress) { mTmpSourceRectF.set(sourceBounds); mTmpDestinationRect.set(sourceBounds); mTmpDestinationRect.inset(insets); @@ -93,9 +94,13 @@ public class PipSurfaceTransactionHelper { : (float) destinationBounds.height() / sourceBounds.height(); } else { // scale by sourceRectHint if it's not edge-to-edge - scale = sourceRectHint.width() <= sourceRectHint.height() + final float endScale = sourceRectHint.width() <= sourceRectHint.height() ? (float) destinationBounds.width() / sourceRectHint.width() : (float) destinationBounds.height() / sourceRectHint.height(); + final float startScale = sourceRectHint.width() <= sourceRectHint.height() + ? (float) destinationBounds.width() / sourceBounds.width() + : (float) destinationBounds.height() / sourceBounds.height(); + scale = (1 - progress) * startScale + progress * endScale; } final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale; final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale; diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index be3dfdcf05d5..c5beaa7ee0b1 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -137,12 +137,14 @@ public class ActivityManagerWrapper { } /** - * @return the task snapshot for the given {@param taskId}. + * @return a {@link ThumbnailData} with {@link TaskSnapshot} for the given {@param taskId}. + * The snapshot will be triggered if no cached {@link TaskSnapshot} exists. */ public @NonNull ThumbnailData getTaskThumbnail(int taskId, boolean isLowResolution) { TaskSnapshot snapshot = null; try { - snapshot = getService().getTaskSnapshot(taskId, isLowResolution); + snapshot = getService().getTaskSnapshot(taskId, isLowResolution, + true /* takeSnapshotIfNeeded */); } catch (RemoteException e) { Log.w(TAG, "Failed to retrieve task snapshot", e); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java index 302ba8444f05..9265f07ad284 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java @@ -105,7 +105,7 @@ public class RemoteAnimationAdapterCompat { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { remoteAnimationAdapter.onAnimationCancelled(); } }; @@ -220,9 +220,9 @@ public class RemoteAnimationAdapterCompat { for (int i = info.getChanges().size() - 1; i >= 0; --i) { info.getChanges().get(i).getLeash().release(); } - for (int i = leashMap.size() - 1; i >= 0; --i) { - leashMap.valueAt(i).release(); - } + // Don't release here since launcher might still be using them. Instead + // let launcher release them (eg. via RemoteAnimationTargets) + leashMap.clear(); try { finishCallback.onTransitionFinished(null /* wct */, finishTransaction); } catch (RemoteException e) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 727d108df339..ede62437e5a0 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -3643,6 +3643,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.sendEmptyMessage(MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED); } + /** + * @return true when the screen is on (including when a screensaver is showing), + * false when the screen is OFF or DOZE (including showing AOD UI) + */ public boolean isDeviceInteractive() { return mDeviceInteractive; } @@ -3785,6 +3789,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab pw.println(" mFingerprintLockedOut=" + mFingerprintLockedOut); pw.println(" mFingerprintLockedOutPermanent=" + mFingerprintLockedOutPermanent); pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId)); + pw.println(" mKeyguardOccluded=" + mKeyguardOccluded); + pw.println(" mIsDreaming=" + mIsDreaming); if (isUdfpsSupported()) { pw.println(" udfpsEnrolled=" + isUdfpsEnrolled()); pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true)); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 378ae14f0327..fef7383634f0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -29,8 +29,7 @@ import android.view.View import android.view.animation.PathInterpolator import com.android.internal.graphics.ColorUtils import com.android.systemui.animation.Interpolators -import com.android.systemui.statusbar.charging.DwellRippleShader -import com.android.systemui.statusbar.charging.RippleShader +import com.android.systemui.ripple.RippleShader private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f @@ -298,7 +297,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { unlockedRippleInProgress = true - rippleShader.shouldFadeOutRipple = true + rippleShader.rippleFill = false drawRipple = true visibility = VISIBLE } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/DwellRippleShader.kt b/packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt index 236129f8eb50..979fe33fb25b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/DwellRippleShader.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.biometrics import android.graphics.PointF import android.graphics.RuntimeShader diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt new file mode 100644 index 000000000000..4986fe85af19 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.camera + +import android.app.ActivityManager +import android.app.ActivityManager.RunningTaskInfo +import android.app.ActivityOptions +import android.app.ActivityTaskManager +import android.content.ContentResolver +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.content.pm.ResolveInfo +import android.os.AsyncTask +import android.os.RemoteException +import android.os.UserHandle +import android.util.Log +import android.view.WindowManager +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.camera.CameraIntents.Companion.isSecureCameraIntent +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.phone.CentralSurfaces +import com.android.systemui.statusbar.phone.PanelViewController +import com.android.systemui.statusbar.policy.KeyguardStateController +import javax.inject.Inject + +/** + * Helps with handling camera-related gestures (for example, double-tap the power button to launch + * the camera). + */ +class CameraGestureHelper @Inject constructor( + private val context: Context, + private val centralSurfaces: CentralSurfaces, + private val keyguardStateController: KeyguardStateController, + private val packageManager: PackageManager, + private val activityManager: ActivityManager, + private val activityStarter: ActivityStarter, + private val activityIntentHelper: ActivityIntentHelper, + private val cameraIntents: CameraIntentsWrapper, + private val contentResolver: ContentResolver, +) { + /** + * Whether the camera application can be launched for the camera launch gesture. + */ + fun canCameraGestureBeLaunched(statusBarState: Int): Boolean { + if (!centralSurfaces.isCameraAllowedByAdmin) { + return false + } + + val resolveInfo: ResolveInfo = packageManager.resolveActivityAsUser( + getStartCameraIntent(), + PackageManager.MATCH_DEFAULT_ONLY, + KeyguardUpdateMonitor.getCurrentUser() + ) + val resolvedPackage = resolveInfo.activityInfo?.packageName + return (resolvedPackage != null && + (statusBarState != StatusBarState.SHADE || + !isForegroundApp(resolvedPackage))) + } + + /** + * Launches the camera. + * + * @param source The source of the camera launch, to be passed to the camera app via [Intent] + */ + fun launchCamera(source: Int) { + val intent: Intent = getStartCameraIntent() + intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source) + val wouldLaunchResolverActivity = activityIntentHelper.wouldLaunchResolverActivity( + intent, KeyguardUpdateMonitor.getCurrentUser() + ) + if (isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) { + AsyncTask.execute { + // Normally an activity will set its requested rotation animation on its window. + // However when launching an activity causes the orientation to change this is too + // late. In these cases, the default animation is used. This doesn't look good for + // the camera (as it rotates the camera contents out of sync with physical reality). + // Therefore, we ask the WindowManager to force the cross-fade animation if an + // orientation change happens to occur during the launch. + val activityOptions = ActivityOptions.makeBasic() + activityOptions.setDisallowEnterPictureInPictureWhileLaunching(true) + activityOptions.rotationAnimationHint = + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS + try { + ActivityTaskManager.getService().startActivityAsUser( + null, + context.basePackageName, + context.attributionTag, + intent, + intent.resolveTypeIfNeeded(contentResolver), + null, + null, + 0, + Intent.FLAG_ACTIVITY_NEW_TASK, + null, + activityOptions.toBundle(), + UserHandle.CURRENT.identifier, + ) + } catch (e: RemoteException) { + Log.w( + PanelViewController.TAG, + "Unable to start camera activity", + e + ) + } + } + } else { + // We need to delay starting the activity because ResolverActivity finishes itself if + // launched from behind the lock-screen. + activityStarter.startActivity(intent, false /* dismissShade */) + } + } + + /** + * Returns an [Intent] that can be used to start the camera app such that it occludes the + * lock-screen, if needed. + */ + private fun getStartCameraIntent(): Intent { + val isLockScreenDismissible = keyguardStateController.canDismissLockScreen() + val isSecure = keyguardStateController.isMethodSecure + return if (isSecure && !isLockScreenDismissible) { + cameraIntents.getSecureCameraIntent() + } else { + cameraIntents.getInsecureCameraIntent() + } + } + + /** + * Returns `true` if the application with the given package name is running in the foreground; + * `false` otherwise + */ + private fun isForegroundApp(packageName: String): Boolean { + val tasks: List<RunningTaskInfo> = activityManager.getRunningTasks(1) + return tasks.isNotEmpty() && packageName == tasks[0].topActivity.packageName + } + + companion object { + private const val EXTRA_CAMERA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt new file mode 100644 index 000000000000..cf02f8fb4a3c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.camera + +import android.content.Context +import android.content.Intent +import javax.inject.Inject + +/** Injectable wrapper around [CameraIntents]. */ +class CameraIntentsWrapper @Inject constructor( + private val context: Context, +) { + + /** + * Returns an [Intent] that can be used to start the camera, suitable for when the device is + * already unlocked + */ + fun getSecureCameraIntent(): Intent { + return CameraIntents.getSecureCameraIntent(context) + } + + /** + * Returns an [Intent] that can be used to start the camera, suitable for when the device is not + * already unlocked + */ + fun getInsecureCameraIntent(): Intent { + return CameraIntents.getInsecureCameraIntent(context) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt index 558bcac681d9..8292e52b1ffd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.charging import android.content.Context import android.content.res.Configuration @@ -32,6 +32,7 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.ripple.RippleView import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController @@ -84,7 +85,7 @@ class WiredChargingRippleController @Inject constructor( private var debounceLevel = 0 @VisibleForTesting - var rippleView: ChargingRippleView = ChargingRippleView(context, attrs = null) + var rippleView: RippleView = RippleView(context, attrs = null) init { pluggedIn = batteryController.isPluggedIn diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java index 0d3e2ae9a776..f6368ee19e8f 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java @@ -34,7 +34,7 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; -import com.android.systemui.statusbar.charging.ChargingRippleView; +import com.android.systemui.ripple.RippleView; import java.text.NumberFormat; @@ -46,7 +46,7 @@ public class WirelessChargingLayout extends FrameLayout { private static final long RIPPLE_ANIMATION_DURATION = 1500; private static final int SCRIM_COLOR = 0x4C000000; private static final int SCRIM_FADE_DURATION = 300; - private ChargingRippleView mRippleView; + private RippleView mRippleView; public WirelessChargingLayout(Context context) { super(context); diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index cd8ca0553add..afc58ef70ee1 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -45,6 +45,7 @@ import android.content.pm.ShortcutManager; import android.content.res.Resources; import android.hardware.SensorManager; import android.hardware.SensorPrivacyManager; +import android.hardware.camera2.CameraManager; import android.hardware.devicestate.DeviceStateManager; import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.ColorDisplayManager; @@ -553,4 +554,10 @@ public class FrameworkServicesModule { static SafetyCenterManager provideSafetyCenterManager(Context context) { return context.getSystemService(SafetyCenterManager.class); } + + @Provides + @Singleton + static CameraManager provideCameraManager(Context context) { + return context.getSystemService(CameraManager.class); + } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 366ef2651a92..ba1e057716f8 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -55,8 +55,6 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.QsFrameTranslateModule; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; @@ -220,11 +218,9 @@ public abstract class SystemUIModule { ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, - NotifPipelineFlags notifPipelineFlags, DumpManager dumpManager, @Main Executor sysuiMainExecutor) { return Optional.ofNullable(BubblesManager.create(context, @@ -240,11 +236,9 @@ public abstract class SystemUIModule { zenModeController, notifUserManager, groupManager, - entryManager, notifCollection, notifPipeline, sysUiState, - notifPipelineFlags, dumpManager, sysuiMainExecutor)); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index d71956d054be..3eb3c80f4081 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -263,7 +263,7 @@ public class KeyguardService extends Service { // already finished (or not started yet), so do nothing. return; } - runner.onAnimationCancelled(); + runner.onAnimationCancelled(false /* isKeyguardOccluded */); origFinishCB.onTransitionFinished(null /* wct */, null /* t */); } catch (RemoteException e) { // nothing, we'll just let it finish on its own I guess. @@ -396,7 +396,7 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { mKeyguardViewMediator.cancelKeyguardExitAnimation(); } }; @@ -453,6 +453,8 @@ public class KeyguardService extends Service { @Override // Binder interface public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardService.mBinder#setOccluded"); checkPermission(); mKeyguardViewMediator.setOccluded(isOccluded, animate); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index be1725b798e2..3480ab68a5da 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -837,13 +837,10 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private final ActivityLaunchAnimator.Controller mOccludeAnimationController = new ActivityLaunchAnimator.Controller() { @Override - public void onLaunchAnimationStart(boolean isExpandingFullyAbove) { - setOccluded(true /* occluded */, false /* animate */); - } + public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {} @Override public void onLaunchAnimationCancelled() { - setOccluded(true /* occluded */, false /* animate */); Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded); } @@ -911,12 +908,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private final Matrix mUnoccludeMatrix = new Matrix(); @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { if (mUnoccludeAnimator != null) { mUnoccludeAnimator.cancel(); } - setOccluded(false /* isOccluded */, false /* animate */); + setOccluded(isKeyguardOccluded /* isOccluded */, false /* animate */); Log.d(TAG, "Unocclude animation cancelled. Occluded state is now: " + mOccluded); } @@ -926,6 +923,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + Log.d(TAG, "UnoccludeAnimator#onAnimationStart. Set occluded = false."); setOccluded(false /* isOccluded */, true /* animate */); if (apps == null || apps.length == 0 || apps[0] == null) { @@ -1677,6 +1675,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, * Notify us when the keyguard is occluded by another window */ public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardViewMediator#setOccluded"); if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded); mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD); @@ -1707,6 +1707,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, */ private void handleSetOccluded(boolean isOccluded, boolean animate) { Trace.beginSection("KeyguardViewMediator#handleSetOccluded"); + Log.d(TAG, "handleSetOccluded(" + isOccluded + ")"); synchronized (KeyguardViewMediator.this) { if (mHiding && isOccluded) { // We're in the process of going away but WindowManager wants to show a @@ -3175,9 +3176,9 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { if (mRunner != null) { - mRunner.onAnimationCancelled(); + mRunner.onAnimationCancelled(isKeyguardOccluded); } } @@ -3214,13 +3215,18 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, // internal state to reflect that immediately, vs. waiting for the launch animator to // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to // be occluded and might re-show the keyguard. + Log.d(TAG, "OccludeAnimator#onAnimationStart. Set occluded = true."); setOccluded(true /* isOccluded */, false /* animate */); } @Override - public void onAnimationCancelled() throws RemoteException { - super.onAnimationCancelled(); - Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded); + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { + super.onAnimationCancelled(isKeyguardOccluded); + + Log.d(TAG, "Occlude animation cancelled by WM. " + + "Setting occluded state to: " + isKeyguardOccluded); + setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 90cca15ddf21..d0da18aaba05 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -27,6 +27,8 @@ import com.android.systemui.log.LogBufferFactory; import com.android.systemui.log.LogcatEchoTracker; import com.android.systemui.log.LogcatEchoTrackerDebug; import com.android.systemui.log.LogcatEchoTrackerProd; +import com.android.systemui.statusbar.notification.NotifPipelineFlags; +import com.android.systemui.util.Compile; import dagger.Module; import dagger.Provides; @@ -48,8 +50,14 @@ public class LogModule { @Provides @SysUISingleton @NotificationLog - public static LogBuffer provideNotificationsLogBuffer(LogBufferFactory factory) { - return factory.create("NotifLog", 1000 /* maxSize */, false /* systrace */); + public static LogBuffer provideNotificationsLogBuffer( + LogBufferFactory factory, + NotifPipelineFlags notifPipelineFlags) { + int maxSize = 1000; + if (Compile.IS_DEBUG && notifPipelineFlags.isDevLoggingEnabled()) { + maxSize *= 10; + } + return factory.create("NotifLog", maxSize, false /* systrace */); } /** Provides a logging buffer for logs related to heads up presentation of notifications. */ diff --git a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt index f1d5e94bfbf3..d0826553ad2c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt @@ -17,20 +17,17 @@ package com.android.systemui.media import android.animation.ArgbEvaluator -import android.animation.ValueAnimator.AnimatorUpdateListener import android.animation.ValueAnimator +import android.animation.ValueAnimator.AnimatorUpdateListener import android.content.Context import android.content.res.ColorStateList -import android.graphics.Color -import android.graphics.drawable.GradientDrawable -import android.graphics.drawable.RippleDrawable import android.content.res.Configuration import android.content.res.Configuration.UI_MODE_NIGHT_YES +import android.graphics.drawable.RippleDrawable import com.android.internal.R import com.android.internal.annotations.VisibleForTesting import com.android.settingslib.Utils import com.android.systemui.monet.ColorScheme -import com.android.systemui.util.getColorWithAlpha /** * A [ColorTransition] is an object that updates the colors of views each time [updateColorScheme] @@ -106,7 +103,6 @@ class ColorSchemeTransition internal constructor( constructor(context: Context, mediaViewHolder: MediaViewHolder) : this(context, mediaViewHolder, ::AnimatingColorTransition) - private var isGradientEnabled = true val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95) val surfaceColor = animatingColorTransitionFactory( bgColor, @@ -187,16 +183,6 @@ class ColorSchemeTransition internal constructor( mediaViewHolder.seekBar.progressBackgroundTintList = ColorStateList.valueOf(textTertiary) } - val bgGradientStart = animatingColorTransitionFactory( - bgColor, - albumGradientPicker(::backgroundStartFromScheme, 0.25f) - ) { _ -> updateAlbumGradient() } - - val bgGradientEnd = animatingColorTransitionFactory( - bgColor, - albumGradientPicker(::backgroundEndFromScheme, 0.9f) - ) { _ -> updateAlbumGradient() } - val colorTransitions = arrayOf( surfaceColor, colorSeamless, @@ -206,37 +192,13 @@ class ColorSchemeTransition internal constructor( textPrimaryInverse, textSecondary, textTertiary, - bgGradientStart, - bgGradientEnd ) - private fun updateAlbumGradient() { - val gradient = mediaViewHolder.albumView.foreground?.mutate() - if (gradient is GradientDrawable) { - gradient.colors = intArrayOf( - bgGradientStart?.currentColor ?: 0, - bgGradientEnd?.currentColor ?: 0) - } - } - - private fun albumGradientPicker( - inner: (ColorScheme) -> Int, - targetAlpha: Float - ): (ColorScheme) -> Int { - return { scheme -> - if (isGradientEnabled) - getColorWithAlpha(inner(scheme), targetAlpha) - else - Color.TRANSPARENT - } - } - private fun loadDefaultColor(id: Int): Int { return Utils.getColorAttr(context, id).defaultColor } - fun updateColorScheme(colorScheme: ColorScheme?, enableGradient: Boolean) { - isGradientEnabled = enableGradient + fun updateColorScheme(colorScheme: ColorScheme?) { colorTransitions.forEach { it.updateColorScheme(colorScheme) } colorScheme?.let { mediaViewHolder.gutsViewHolder.colorScheme = colorScheme } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 68aba6217f8e..1ed65b31dbd0 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -38,7 +38,9 @@ import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.Icon; +import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.TransitionDrawable; import android.media.session.MediaController; import android.media.session.MediaSession; @@ -82,6 +84,7 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.ColorUtilKt; import com.android.systemui.util.animation.TransitionLayout; import com.android.systemui.util.time.SystemClock; @@ -683,7 +686,18 @@ public class MediaControlPanel { WallpaperColors wallpaperColors = WallpaperColors .fromBitmap(artworkIcon.getBitmap()); mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT); - artwork = getScaledBackground(artworkIcon, width, height); + Drawable albumArt = getScaledBackground(artworkIcon, width, height); + GradientDrawable gradient = (GradientDrawable) mContext + .getDrawable(R.drawable.qs_media_scrim); + gradient.setColors(new int[] { + ColorUtilKt.getColorWithAlpha( + MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme), + 0.25f), + ColorUtilKt.getColorWithAlpha( + MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme), + 0.9f), + }); + artwork = new LayerDrawable(new Drawable[] { albumArt, gradient }); isArtworkBound = true; } else { // If there's no artwork, use colors from the app icon @@ -735,7 +749,7 @@ public class MediaControlPanel { } // Transition Colors to current color scheme - mColorSchemeTransition.updateColorScheme(colorScheme, mIsArtworkBound); + mColorSchemeTransition.updateColorScheme(colorScheme); // App icon - use notification icon ImageView appIconView = mMediaViewHolder.getAppIcon(); diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt index fe1ac80e24df..c9fce794f57f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt @@ -25,17 +25,14 @@ import android.graphics.drawable.Drawable import android.os.PowerManager import android.os.SystemClock import android.util.Log -import android.view.Gravity import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT -import android.widget.LinearLayout import com.android.internal.widget.CachingIconView import com.android.settingslib.Utils import com.android.systemui.R @@ -57,7 +54,7 @@ import com.android.systemui.util.view.ViewUtil abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>( internal val context: Context, internal val logger: MediaTttLogger, - private val windowManager: WindowManager, + internal val windowManager: WindowManager, private val viewUtil: ViewUtil, @Main private val mainExecutor: DelayableExecutor, private val accessibilityManager: AccessibilityManager, @@ -65,12 +62,15 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>( private val powerManager: PowerManager, @LayoutRes private val chipLayoutRes: Int ) { - /** The window layout parameters we'll use when attaching the view to a window. */ + + /** + * Window layout params that will be used as a starting point for the [windowLayoutParams] of + * all subclasses. + */ @SuppressLint("WrongConstant") // We're allowed to use TYPE_VOLUME_OVERLAY - private val windowLayoutParams = WindowManager.LayoutParams().apply { + internal val commonWindowLayoutParams = WindowManager.LayoutParams().apply { width = WindowManager.LayoutParams.WRAP_CONTENT height = WindowManager.LayoutParams.WRAP_CONTENT - gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL title = WINDOW_TITLE @@ -78,6 +78,14 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>( setTrustedOverlay() } + /** + * The window layout parameters we'll use when attaching the view to a window. + * + * Subclasses must override this to provide their specific layout params, and they should use + * [commonWindowLayoutParams] as part of their layout params. + */ + internal abstract val windowLayoutParams: WindowManager.LayoutParams + /** The chip view currently being displayed. Null if the chip is not being displayed. */ private var chipView: ViewGroup? = null diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt index a5d763c5327b..99a5b8b2d450 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt @@ -16,17 +16,23 @@ package com.android.systemui.media.taptotransfer.receiver +import android.annotation.SuppressLint import android.app.StatusBarManager import android.content.Context +import android.graphics.PointF import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.media.MediaRoute2Info import android.os.Handler import android.os.PowerManager import android.util.Log +import android.view.Gravity +import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager +import androidx.core.graphics.ColorUtils +import com.android.settingslib.Utils import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main @@ -36,6 +42,7 @@ import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCom import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.gesture.TapGestureDetector +import com.android.systemui.util.animation.AnimationUtil.Companion.frames import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.view.ViewUtil import javax.inject.Inject @@ -69,6 +76,17 @@ class MediaTttChipControllerReceiver @Inject constructor( powerManager, R.layout.media_ttt_chip_receiver ) { + @SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS + override val windowLayoutParams = commonWindowLayoutParams.apply { + gravity = Gravity.BOTTOM.or(Gravity.CENTER_HORIZONTAL) + // Params below are needed for the ripple to work correctly + width = WindowManager.LayoutParams.MATCH_PARENT + height = WindowManager.LayoutParams.MATCH_PARENT + layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS + fitInsetsTypes = 0 // Ignore insets from all system bars + flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + } + private val commandQueueCallbacks = object : CommandQueue.Callbacks { override fun updateMediaTapToTransferReceiverDisplay( @StatusBarManager.MediaTransferReceiverState displayState: Int, @@ -131,6 +149,19 @@ class MediaTttChipControllerReceiver @Inject constructor( ) } + override fun animateChipIn(chipView: ViewGroup) { + val appIconView = chipView.requireViewById<View>(R.id.app_icon) + appIconView.animate() + .translationYBy(-1 * getTranslationAmount().toFloat()) + .setDuration(30.frames) + .start() + appIconView.animate() + .alpha(1f) + .setDuration(5.frames) + .start() + startRipple(chipView.requireViewById(R.id.ripple)) + } + override fun getIconSize(isAppIcon: Boolean): Int? = context.resources.getDimensionPixelSize( if (isAppIcon) { @@ -139,6 +170,45 @@ class MediaTttChipControllerReceiver @Inject constructor( R.dimen.media_ttt_generic_icon_size_receiver } ) + + /** Returns the amount that the chip will be translated by in its intro animation. */ + private fun getTranslationAmount(): Int { + return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation) + } + + private fun startRipple(rippleView: ReceiverChipRippleView) { + if (rippleView.rippleInProgress) { + // Skip if ripple is still playing + return + } + rippleView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { + override fun onViewDetachedFromWindow(view: View?) {} + + override fun onViewAttachedToWindow(view: View?) { + if (view == null) { + return + } + val attachedRippleView = view as ReceiverChipRippleView + layoutRipple(attachedRippleView) + attachedRippleView.startRipple() + attachedRippleView.removeOnAttachStateChangeListener(this) + } + }) + } + + private fun layoutRipple(rippleView: ReceiverChipRippleView) { + val windowBounds = windowManager.currentWindowMetrics.bounds + val height = windowBounds.height() + val width = windowBounds.width() + + rippleView.radius = height / 5f + // Center the ripple on the bottom of the screen in the middle. + rippleView.origin = PointF(/* x= */ width / 2f, /* y= */ height.toFloat()) + + val color = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColorAccent) + val colorWithAlpha = ColorUtils.setAlphaComponent(color, 70) + rippleView.setColor(colorWithAlpha) + } } data class ChipReceiverInfo( diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt new file mode 100644 index 000000000000..fed546bf52c2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt @@ -0,0 +1,33 @@ +/* + * 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.systemui.media.taptotransfer.receiver + +import android.content.Context +import android.util.AttributeSet +import com.android.systemui.ripple.RippleView + +/** + * An expanding ripple effect for the media tap-to-transfer receiver chip. + */ +class ReceiverChipRippleView( + context: Context?, attrs: AttributeSet? +) : RippleView(context, attrs) { + init { + setRippleFill(true) + duration = 3000L + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt index 943604cff887..797a7701413b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt @@ -21,6 +21,7 @@ import android.content.Context import android.media.MediaRoute2Info import android.os.PowerManager import android.util.Log +import android.view.Gravity import android.view.View import android.view.ViewGroup import android.view.WindowManager @@ -69,6 +70,10 @@ class MediaTttChipControllerSender @Inject constructor( powerManager, R.layout.media_ttt_chip ) { + override val windowLayoutParams = commonWindowLayoutParams.apply { + gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) + } + private var currentlyDisplayedChipState: ChipStateSender? = null private val commandQueueCallbacks = object : CommandQueue.Callbacks { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 730f88ab9f8f..5f52485a5481 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -105,6 +105,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.LatencyTracker; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Gefingerpoken; @@ -1069,7 +1070,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 1abf9903c08d..9e0c49641e72 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -57,6 +57,7 @@ import android.view.WindowInsetsController.Behavior; import androidx.annotation.NonNull; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; @@ -357,7 +358,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, @Override public void onSystemBarAttributesChanged(int displayId, int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, int behavior, - InsetsVisibilities requestedVisibilities, String packageName) { + InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { mOverviewProxyService.onSystemBarAttributesChanged(displayId, behavior); boolean nbModeChanged = false; if (mAppearance != appearance) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index fbdabc74aba4..a1c66b35bacc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -396,7 +396,6 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D } void saveTilesToSettings(List<String> tileSpecs) { - if (tileSpecs.contains("work")) Log.wtfStack(TAG, "Saving work tile"); mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs), null /* tag */, false /* default */, mCurrentUser, true /* overrideable by restore */); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt b/packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt index bdad36c58480..93a2efc4e96d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt +++ b/packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.ripple import android.graphics.PointF import android.graphics.RuntimeShader @@ -148,7 +148,7 @@ class RippleShader internal constructor() : RuntimeShader(SHADER) { val fadeOutNoise = subProgress(0.4f, 1f, value) var fadeOutRipple = 0f var fadeCircle = 0f - if (shouldFadeOutRipple) { + if (!rippleFill) { fadeCircle = subProgress(0f, 0.2f, value) fadeOutRipple = subProgress(0.3f, 1f, value) } @@ -202,5 +202,9 @@ class RippleShader internal constructor() : RuntimeShader(SHADER) { setFloatUniform("in_pixelDensity", value) } - var shouldFadeOutRipple: Boolean = true + /** + * True if the ripple should stayed filled in as it expands to give a filled-in circle effect. + * False for a ring effect. + */ + var rippleFill: Boolean = false } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt b/packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt index 10e90fee1469..fc52464ecf85 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.ripple import android.animation.Animator import android.animation.AnimatorListenerAdapter @@ -30,9 +30,10 @@ import android.view.View private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.3f /** - * Expanding ripple effect that shows when charging begins. + * A generic expanding ripple effect. To trigger the ripple expansion, set [radius] and [origin], + * then call [startRipple]. */ -class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { +open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private val rippleShader = RippleShader() private val defaultColor: Int = 0xffffffff.toInt() private val ripplePaint = Paint() @@ -74,9 +75,9 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context } val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = duration - animator.addUpdateListener { animator -> - val now = animator.currentPlayTime - val progress = animator.animatedValue as Float + animator.addUpdateListener { updateListener -> + val now = updateListener.currentPlayTime + val progress = updateListener.animatedValue as Float rippleShader.progress = progress rippleShader.distortionStrength = 1 - progress rippleShader.time = now.toFloat() @@ -92,10 +93,20 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context rippleInProgress = true } + /** Set the color to be used for the ripple. */ fun setColor(color: Int) { rippleShader.color = color } + /** + * Set whether the ripple should remain filled as the ripple expands. + * + * See [RippleShader.rippleFill]. + */ + fun setRippleFill(rippleFill: Boolean) { + rippleShader.rippleFill = rippleFill + } + override fun onDraw(canvas: Canvas?) { if (canvas == null || !canvas.isHardwareAccelerated) { // Drawing with the ripple shader requires hardware acceleration, so skip @@ -107,6 +118,6 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context // animation implementation in the ripple shader. val maskRadius = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) * (1 - rippleShader.progress)) * radius * 2 - canvas?.drawCircle(origin.x, origin.y, maskRadius, ripplePaint) + canvas.drawCircle(origin.x, origin.y, maskRadius, ripplePaint) } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 5b6e5ce95b14..c213f192291a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -142,7 +142,7 @@ public class ScreenshotController { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index cc3121ddc0e9..e99244048fd6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -66,6 +66,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IAddTileResultCallback; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.GcUtils; import com.android.internal.view.AppearanceRegion; @@ -361,7 +362,7 @@ public class CommandQueue extends IStatusBar.Stub implements default void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { } + String packageName, LetterboxDetails[] letterboxDetails) { } /** * @see IStatusBar#showTransient(int, int[], boolean). @@ -1090,7 +1091,8 @@ public class CommandQueue extends IStatusBar.Stub implements @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.argi1 = displayId; @@ -1100,6 +1102,7 @@ public class CommandQueue extends IStatusBar.Stub implements args.argi4 = behavior; args.arg2 = requestedVisibilities; args.arg3 = packageName; + args.arg4 = letterboxDetails; mHandler.obtainMessage(MSG_SYSTEM_BAR_CHANGED, args).sendToTarget(); } } @@ -1561,7 +1564,8 @@ public class CommandQueue extends IStatusBar.Stub implements for (int i = 0; i < mCallbacks.size(); i++) { mCallbacks.get(i).onSystemBarAttributesChanged(args.argi1, args.argi2, (AppearanceRegion[]) args.arg1, args.argi3 == 1, args.argi4, - (InsetsVisibilities) args.arg2, (String) args.arg3); + (InsetsVisibilities) args.arg2, (String) args.arg3, + (LetterboxDetails[]) args.arg4); } args.recycle(); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 1ce05ec7e7ad..c900c5a2ff0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -36,7 +36,6 @@ import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.os.AsyncTask; import android.os.Trace; -import android.service.notification.NotificationListenerService; import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.util.ArraySet; @@ -44,7 +43,6 @@ import android.util.Log; import android.view.View; import android.widget.ImageView; -import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.animation.Interpolators; @@ -56,9 +54,6 @@ import com.android.systemui.media.MediaDataManager; import com.android.systemui.media.SmartspaceMediaData; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.dagger.CentralSurfacesModule; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -112,11 +107,9 @@ public class NotificationMediaManager implements Dumpable { } private final NotificationVisibilityProvider mVisibilityProvider; - private final NotificationEntryManager mEntryManager; private final MediaDataManager mMediaDataManager; private final NotifPipeline mNotifPipeline; private final NotifCollection mNotifCollection; - private final boolean mUsingNotifPipeline; @Nullable private Lazy<NotificationShadeWindowController> mNotificationShadeWindowController; @@ -180,12 +173,10 @@ public class NotificationMediaManager implements Dumpable { Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy, Lazy<NotificationShadeWindowController> notificationShadeWindowController, NotificationVisibilityProvider visibilityProvider, - NotificationEntryManager notificationEntryManager, MediaArtworkProcessor mediaArtworkProcessor, KeyguardBypassController keyguardBypassController, NotifPipeline notifPipeline, NotifCollection notifCollection, - NotifPipelineFlags notifPipelineFlags, @Main DelayableExecutor mainExecutor, MediaDataManager mediaDataManager, DumpManager dumpManager) { @@ -197,19 +188,12 @@ public class NotificationMediaManager implements Dumpable { mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy; mNotificationShadeWindowController = notificationShadeWindowController; mVisibilityProvider = visibilityProvider; - mEntryManager = notificationEntryManager; mMainExecutor = mainExecutor; mMediaDataManager = mediaDataManager; mNotifPipeline = notifPipeline; mNotifCollection = notifCollection; - if (!notifPipelineFlags.isNewPipelineEnabled()) { - setupNEM(); - mUsingNotifPipeline = false; - } else { - setupNotifPipeline(); - mUsingNotifPipeline = true; - } + setupNotifPipeline(); dumpManager.registerDumpable(this); } @@ -273,79 +257,6 @@ public class NotificationMediaManager implements Dumpable { }); } - private void setupNEM() { - mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { - - @Override - public void onPendingEntryAdded(NotificationEntry entry) { - mMediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn()); - } - - @Override - public void onPreEntryUpdated(NotificationEntry entry) { - mMediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn()); - } - - @Override - public void onEntryInflated(NotificationEntry entry) { - findAndUpdateMediaNotifications(); - } - - @Override - public void onEntryReinflated(NotificationEntry entry) { - findAndUpdateMediaNotifications(); - } - - @Override - public void onEntryRemoved( - @NonNull NotificationEntry entry, - @Nullable NotificationVisibility visibility, - boolean removedByUser, - int reason) { - removeEntry(entry); - } - }); - - // Pending entries are never inflated, and will never generate a call to onEntryRemoved(). - // This can happen when notifications are added and canceled before inflation. Add this - // separate listener for cleanup, since media inflation occurs onPendingEntryAdded(). - mEntryManager.addCollectionListener(new NotifCollectionListener() { - @Override - public void onEntryCleanUp(@NonNull NotificationEntry entry) { - removeEntry(entry); - } - }); - - mMediaDataManager.addListener(new MediaDataManager.Listener() { - @Override - public void onMediaDataLoaded(@NonNull String key, - @Nullable String oldKey, @NonNull MediaData data, boolean immediately, - int receivedSmartspaceCardLatency, boolean isSsReactivated) { - } - - @Override - public void onSmartspaceMediaDataLoaded(@NonNull String key, - @NonNull SmartspaceMediaData data, boolean shouldPrioritize) { - - } - - @Override - public void onMediaDataRemoved(@NonNull String key) { - NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key); - if (entry != null) { - // TODO(b/160713608): "removing" this notification won't happen and - // won't send the 'deleteIntent' if the notification is ongoing. - mEntryManager.performRemoveNotification(entry.getSbn(), - getDismissedByUserStats(entry), - NotificationListenerService.REASON_CANCEL); - } - } - - @Override - public void onSmartspaceMediaDataRemoved(@NonNull String key, boolean immediately) {} - }); - } - private DismissedByUserStats getDismissedByUserStats(NotificationEntry entry) { return new DismissedByUserStats( NotificationStats.DISMISSAL_SHADE, // Add DISMISSAL_MEDIA? @@ -401,22 +312,10 @@ public class NotificationMediaManager implements Dumpable { if (mMediaNotificationKey == null) { return null; } - if (mUsingNotifPipeline) { - return Optional.ofNullable(mNotifPipeline.getEntry(mMediaNotificationKey)) - .map(entry -> entry.getIcons().getShelfIcon()) - .map(StatusBarIconView::getSourceIcon) - .orElse(null); - } else { - synchronized (mEntryManager) { - NotificationEntry entry = mEntryManager - .getActiveNotificationUnfiltered(mMediaNotificationKey); - if (entry == null || entry.getIcons().getShelfIcon() == null) { - return null; - } - - return entry.getIcons().getShelfIcon().getSourceIcon(); - } - } + return Optional.ofNullable(mNotifPipeline.getEntry(mMediaNotificationKey)) + .map(entry -> entry.getIcons().getShelfIcon()) + .map(StatusBarIconView::getSourceIcon) + .orElse(null); } public void addCallback(MediaListener callback) { @@ -431,21 +330,9 @@ public class NotificationMediaManager implements Dumpable { public void findAndUpdateMediaNotifications() { boolean metaDataChanged; - if (mUsingNotifPipeline) { - // TODO(b/169655907): get the semi-filtered notifications for current user - Collection<NotificationEntry> allNotifications = mNotifPipeline.getAllNotifs(); - metaDataChanged = findPlayingMediaNotification(allNotifications); - } else { - synchronized (mEntryManager) { - Collection<NotificationEntry> allNotifications = mEntryManager.getAllNotifs(); - metaDataChanged = findPlayingMediaNotification(allNotifications); - } - - if (metaDataChanged) { - mEntryManager.updateNotifications("NotificationMediaManager - metaDataChanged"); - } - - } + // TODO(b/169655907): get the semi-filtered notifications for current user + Collection<NotificationEntry> allNotifications = mNotifPipeline.getAllNotifs(); + metaDataChanged = findPlayingMediaNotification(allNotifications); dispatchUpdateMediaMetaData(metaDataChanged, true /* allowEnterAnimation */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java index 03d66eede0e4..587c23b39dd3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java @@ -139,12 +139,10 @@ public interface CentralSurfacesDependenciesModule { Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy, Lazy<NotificationShadeWindowController> notificationShadeWindowController, NotificationVisibilityProvider visibilityProvider, - NotificationEntryManager notificationEntryManager, MediaArtworkProcessor mediaArtworkProcessor, KeyguardBypassController keyguardBypassController, NotifPipeline notifPipeline, NotifCollection notifCollection, - NotifPipelineFlags notifPipelineFlags, @Main DelayableExecutor mainExecutor, MediaDataManager mediaDataManager, DumpManager dumpManager) { @@ -153,12 +151,10 @@ public interface CentralSurfacesDependenciesModule { centralSurfacesOptionalLazy, notificationShadeWindowController, visibilityProvider, - notificationEntryManager, mediaArtworkProcessor, keyguardBypassController, notifPipeline, notifCollection, - notifPipelineFlags, mainExecutor, mediaDataManager, dumpManager); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java index e345aabc6215..d99b5f9df12a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java @@ -310,7 +310,7 @@ public class NotifCollection implements Dumpable { } locallyDismissNotifications(entriesToLocallyDismiss); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("dismissNotifications"); } /** @@ -354,7 +354,7 @@ public class NotifCollection implements Dumpable { } locallyDismissNotifications(entries); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("dismissAllNotifications"); } /** @@ -401,7 +401,7 @@ public class NotifCollection implements Dumpable { postNotification(sbn, requireRanking(rankingMap, sbn.getKey())); applyRanking(rankingMap); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onNotificationPosted"); } private void onNotificationGroupPosted(List<CoalescedEvent> batch) { @@ -412,7 +412,7 @@ public class NotifCollection implements Dumpable { for (CoalescedEvent event : batch) { postNotification(event.getSbn(), event.getRanking()); } - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onNotificationGroupPosted"); } private void onNotificationRemoved( @@ -433,14 +433,14 @@ public class NotifCollection implements Dumpable { entry.mCancellationReason = reason; tryRemoveNotification(entry); applyRanking(rankingMap); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onNotificationRemoved"); } private void onNotificationRankingUpdate(RankingMap rankingMap) { Assert.isMainThread(); mEventQueue.add(new RankingUpdatedEvent(rankingMap)); applyRanking(rankingMap); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onNotificationRankingUpdate"); } private void onNotificationChannelModified( @@ -450,7 +450,7 @@ public class NotifCollection implements Dumpable { int modificationType) { Assert.isMainThread(); mEventQueue.add(new ChannelChangedEvent(pkgName, user, channel, modificationType)); - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onNotificationChannelModified"); } private void onNotificationsInitialized() { @@ -610,7 +610,7 @@ public class NotifCollection implements Dumpable { mEventQueue.add(new RankingAppliedEvent()); } - private void dispatchEventsAndRebuildList() { + private void dispatchEventsAndRebuildList(String reason) { Trace.beginSection("NotifCollection.dispatchEventsAndRebuildList"); mAmDispatchingToOtherCode = true; while (!mEventQueue.isEmpty()) { @@ -619,7 +619,7 @@ public class NotifCollection implements Dumpable { mAmDispatchingToOtherCode = false; if (mBuildListener != null) { - mBuildListener.onBuildList(mReadOnlyNotificationSet); + mBuildListener.onBuildList(mReadOnlyNotificationSet, reason); } Trace.endSection(); } @@ -654,7 +654,7 @@ public class NotifCollection implements Dumpable { if (!isLifetimeExtended(entry)) { if (tryRemoveNotification(entry)) { - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("onEndLifetimeExtension"); } } } @@ -955,7 +955,7 @@ public class NotifCollection implements Dumpable { mEventQueue.add(new EntryUpdatedEvent(entry, false /* fromSystem */)); // Skip the applyRanking step and go straight to dispatching the events - dispatchEventsAndRebuildList(); + dispatchEventsAndRebuildList("updateNotificationInternally"); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java index 6441d2fd94af..93761f580dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java @@ -304,11 +304,11 @@ public class ShadeListBuilder implements Dumpable { private final CollectionReadyForBuildListener mReadyForBuildListener = new CollectionReadyForBuildListener() { @Override - public void onBuildList(Collection<NotificationEntry> entries) { + public void onBuildList(Collection<NotificationEntry> entries, String reason) { Assert.isMainThread(); mPipelineState.requireIsBefore(STATE_BUILD_STARTED); - mLogger.logOnBuildList(); + mLogger.logOnBuildList(reason); mAllEntries = entries; mChoreographer.schedule(); } @@ -456,7 +456,8 @@ public class ShadeListBuilder implements Dumpable { mLogger.logEndBuildList( mIterationCount, mReadOnlyNotifList.size(), - countChildren(mReadOnlyNotifList)); + countChildren(mReadOnlyNotifList), + /* enforcedVisualStability */ !mNotifStabilityManager.isEveryChangeAllowed()); if (mAlwaysLogList || mIterationCount % 10 == 0) { Trace.beginSection("ShadeListBuilder.logFinalList"); mLogger.logFinalList(mNotifList); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt index 8d1759b8f475..10a627d65b83 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt @@ -21,31 +21,42 @@ import com.android.systemui.log.LogLevel.DEBUG import com.android.systemui.log.LogLevel.INFO import com.android.systemui.log.LogLevel.WARNING import com.android.systemui.log.dagger.NotificationLog +import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter import com.android.systemui.statusbar.notification.logKey +import com.android.systemui.util.Compile import javax.inject.Inject class ShadeListBuilderLogger @Inject constructor( + notifPipelineFlags: NotifPipelineFlags, @NotificationLog private val buffer: LogBuffer ) { - fun logOnBuildList() { + fun logOnBuildList(reason: String?) { buffer.log(TAG, INFO, { + str1 = reason }, { - "Request received from NotifCollection" + "Request received from NotifCollection for $str1" }) } - fun logEndBuildList(buildId: Int, topLevelEntries: Int, numChildren: Int) { + fun logEndBuildList( + buildId: Int, + topLevelEntries: Int, + numChildren: Int, + enforcedVisualStability: Boolean + ) { buffer.log(TAG, INFO, { long1 = buildId.toLong() int1 = topLevelEntries int2 = numChildren + bool1 = enforcedVisualStability }, { - "(Build $long1) Build complete ($int1 top-level entries, $int2 children)" + "(Build $long1) Build complete ($int1 top-level entries, $int2 children)" + + " enforcedVisualStability=$bool1" }) } @@ -280,6 +291,8 @@ class ShadeListBuilderLogger @Inject constructor( }) } + val logRankInFinalList = Compile.IS_DEBUG && notifPipelineFlags.isDevLoggingEnabled() + fun logFinalList(entries: List<ListEntry>) { if (entries.isEmpty()) { buffer.log(TAG, DEBUG, {}, { "(empty list)" }) @@ -289,16 +302,20 @@ class ShadeListBuilderLogger @Inject constructor( buffer.log(TAG, DEBUG, { int1 = i str1 = entry.logKey + bool1 = logRankInFinalList + int2 = entry.representativeEntry!!.ranking.rank }, { - "[$int1] $str1" + "[$int1] $str1".let { if (bool1) "$it rank=$int2" else it } }) if (entry is GroupEntry) { entry.summary?.let { buffer.log(TAG, DEBUG, { str1 = it.logKey + bool1 = logRankInFinalList + int2 = it.ranking.rank }, { - " [*] $str1 (summary)" + " [*] $str1 (summary)".let { if (bool1) "$it rank=$int2" else it } }) } for (j in entry.children.indices) { @@ -306,8 +323,10 @@ class ShadeListBuilderLogger @Inject constructor( buffer.log(TAG, DEBUG, { int1 = j str1 = child.logKey + bool1 = logRankInFinalList + int2 = child.ranking.rank }, { - " [$int1] $str1" + " [$int1] $str1".let { if (bool1) "$it rank=$int2" else it } }) } } @@ -318,4 +337,4 @@ class ShadeListBuilderLogger @Inject constructor( buffer.log(TAG, INFO, {}) { "Suppressing pipeline run during animation." } } -private const val TAG = "ShadeListBuilder"
\ No newline at end of file +private const val TAG = "ShadeListBuilder" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CollectionReadyForBuildListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CollectionReadyForBuildListener.java index 4023474bf6a7..941b2ae4f771 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CollectionReadyForBuildListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CollectionReadyForBuildListener.java @@ -29,5 +29,5 @@ public interface CollectionReadyForBuildListener { * Called by the NotifCollection to indicate that something in the collection has changed and * that the list builder should regenerate the list. */ - void onBuildList(Collection<NotificationEntry> entries); + void onBuildList(Collection<NotificationEntry> entries, String reason); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 4013254c6592..6d513d0da5c1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -24,8 +24,7 @@ import android.util.MathUtils; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.VisibleForTesting; - +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.SystemBarUtils; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.R; @@ -65,6 +64,9 @@ public class StackScrollAlgorithm { private int mPinnedZTranslationExtra; private float mNotificationScrimPadding; private int mMarginBottom; + private float mQuickQsOffsetHeight; + private float mSmallCornerRadius; + private float mLargeCornerRadius; public StackScrollAlgorithm( Context context, @@ -74,10 +76,10 @@ public class StackScrollAlgorithm { } public void initView(Context context) { - initConstants(context); + updateResources(context); } - private void initConstants(Context context) { + private void updateResources(Context context) { Resources res = context.getResources(); mPaddingBetweenElements = res.getDimensionPixelSize( R.dimen.notification_divider_height); @@ -93,6 +95,9 @@ public class StackScrollAlgorithm { R.dimen.notification_section_divider_height_lockscreen); mNotificationScrimPadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings); mMarginBottom = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom); + mQuickQsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(context); + mSmallCornerRadius = res.getDimension(R.dimen.notification_corner_radius_small); + mLargeCornerRadius = res.getDimension(R.dimen.notification_corner_radius); } /** @@ -441,6 +446,15 @@ public class StackScrollAlgorithm { return false; } + @VisibleForTesting + void maybeUpdateHeadsUpIsVisible(ExpandableViewState viewState, boolean isShadeExpanded, + boolean mustStayOnScreen, boolean topVisible, float viewEnd, float hunMax) { + + if (isShadeExpanded && mustStayOnScreen && topVisible) { + viewState.headsUpIsVisible = viewEnd < hunMax; + } + } + // TODO(b/172289889) polish shade open from HUN /** * Populates the {@link ExpandableViewState} for a single child. @@ -474,14 +488,6 @@ public class StackScrollAlgorithm { : ShadeInterpolation.getContentAlpha(expansion); } - if (ambientState.isShadeExpanded() && view.mustStayOnScreen() - && viewState.yTranslation >= 0) { - // Even if we're not scrolled away we're in view and we're also not in the - // shelf. We can relax the constraints and let us scroll off the top! - float end = viewState.yTranslation + viewState.height + ambientState.getStackY(); - viewState.headsUpIsVisible = end < ambientState.getMaxHeadsUpTranslation(); - } - final float expansionFraction = getExpansionFractionWithoutShelf( algorithmState, ambientState); @@ -497,8 +503,15 @@ public class StackScrollAlgorithm { algorithmState.mCurrentExpandedYPosition += gap; } + // Must set viewState.yTranslation _before_ use. + // Incoming views have yTranslation=0 by default. viewState.yTranslation = algorithmState.mCurrentYPosition; + maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(), + view.mustStayOnScreen(), /* topVisible */ viewState.yTranslation >= 0, + /* viewEnd */ viewState.yTranslation + viewState.height + ambientState.getStackY(), + /* hunMax */ ambientState.getMaxHeadsUpTranslation() + ); if (view instanceof FooterView) { final boolean shadeClosed = !ambientState.isShadeExpanded(); final boolean isShelfShowing = algorithmState.firstViewInShelf != null; @@ -682,7 +695,8 @@ public class StackScrollAlgorithm { if (row.mustStayOnScreen() && !childState.headsUpIsVisible && !row.showingPulsing()) { // Ensure that the heads up is always visible even when scrolled off - clampHunToTop(ambientState, row, childState); + clampHunToTop(mQuickQsOffsetHeight, ambientState.getStackTranslation(), + row.getCollapsedHeight(), childState); if (isTopEntry && row.isAboveShelf()) { // the first hun can't get off screen. clampHunToMaxTranslation(ambientState, row, childState); @@ -719,27 +733,62 @@ public class StackScrollAlgorithm { } } - private void clampHunToTop(AmbientState ambientState, ExpandableNotificationRow row, - ExpandableViewState childState) { - float newTranslation = Math.max(ambientState.getTopPadding() - + ambientState.getStackTranslation(), childState.yTranslation); - childState.height = (int) Math.max(childState.height - (newTranslation - - childState.yTranslation), row.getCollapsedHeight()); - childState.yTranslation = newTranslation; + /** + * When shade is open and we are scrolled to the bottom of notifications, + * clamp incoming HUN in its collapsed form, right below qs offset. + * Transition pinned collapsed HUN to full height when scrolling back up. + */ + @VisibleForTesting + void clampHunToTop(float quickQsOffsetHeight, float stackTranslation, float collapsedHeight, + ExpandableViewState viewState) { + + final float newTranslation = Math.max(quickQsOffsetHeight + stackTranslation, + viewState.yTranslation); + + // Transition from collapsed pinned state to fully expanded state + // when the pinned HUN approaches its actual location (when scrolling back to top). + final float distToRealY = newTranslation - viewState.yTranslation; + viewState.height = (int) Math.max(viewState.height - distToRealY, collapsedHeight); + viewState.yTranslation = newTranslation; } + // Pin HUN to bottom of expanded QS + // while the rest of notifications are scrolled offscreen. private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row, ExpandableViewState childState) { - float newTranslation; float maxHeadsUpTranslation = ambientState.getMaxHeadsUpTranslation(); - float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding() + final float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding() + ambientState.getStackTranslation(); maxHeadsUpTranslation = Math.min(maxHeadsUpTranslation, maxShelfPosition); - float bottomPosition = maxHeadsUpTranslation - row.getCollapsedHeight(); - newTranslation = Math.min(childState.yTranslation, bottomPosition); + + final float bottomPosition = maxHeadsUpTranslation - row.getCollapsedHeight(); + final float newTranslation = Math.min(childState.yTranslation, bottomPosition); childState.height = (int) Math.min(childState.height, maxHeadsUpTranslation - newTranslation); childState.yTranslation = newTranslation; + + // Animate pinned HUN bottom corners to and from original roundness. + final float originalCornerRadius = + row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius); + final float roundness = computeCornerRoundnessForPinnedHun(mHostView.getHeight(), + ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius); + row.setBottomRoundness(roundness, /* animate= */ false); + } + + @VisibleForTesting + float computeCornerRoundnessForPinnedHun(float hostViewHeight, float stackY, + float viewMaxHeight, float originalCornerRadius) { + + // Compute y where corner roundness should be in its original unpinned state. + // We use view max height because the pinned collapsed HUN expands to max height + // when it becomes unpinned. + final float originalRoundnessY = hostViewHeight - viewMaxHeight; + + final float distToOriginalRoundness = Math.max(0f, stackY - originalRoundnessY); + final float progressToPinnedRoundness = Math.min(1f, + distToOriginalRoundness / viewMaxHeight); + + return MathUtils.lerp(originalCornerRadius, 1f, progressToPinnedRoundness); } protected int getMaxAllowedChildHeight(View child) { 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 39620ac23117..a0f386ff0b5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -448,7 +448,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } // During wake and unlock, we need to draw black before waking up to avoid abrupt // brightness changes due to display state transitions. - boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn(); Runnable wakeUp = ()-> { if (!wasDeviceInteractive) { if (DEBUG_BIO_WAKELOCK) { @@ -659,7 +658,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp mLatencyTracker.onActionCancel(action); } - if (biometricSourceType == BiometricSourceType.FINGERPRINT + if (!mVibratorHelper.hasVibrator() + && (!mUpdateMonitor.isDeviceInteractive() || mUpdateMonitor.isDreaming())) { + startWakeAndUnlock(MODE_SHOW_BOUNCER); + } else if (biometricSourceType == BiometricSourceType.FINGERPRINT && mUpdateMonitor.isUdfpsSupported()) { long currUptimeMillis = SystemClock.uptimeMillis(); if (currUptimeMillis - mLastFpFailureUptimeMillis < mConsecutiveFpFailureThreshold) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index 38c37f03f643..cb9afe887ab7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -45,6 +45,7 @@ import android.view.WindowInsetsController.Behavior; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; @@ -463,7 +464,8 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } 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 4f99deaaf799..2daa4759457d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -139,6 +139,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.camera.CameraIntents; +import com.android.systemui.charging.WiredChargingRippleController; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -197,7 +198,6 @@ import com.android.systemui.statusbar.PowerButtonReveal; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; -import com.android.systemui.statusbar.charging.WiredChargingRippleController; import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.core.StatusBarInitializer; import com.android.systemui.statusbar.notification.DynamicPrivacyController; @@ -974,7 +974,7 @@ public class CentralSurfacesImpl extends CoreStartable implements } mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior, - result.mRequestedVisibilities, result.mPackageName); + result.mRequestedVisibilities, result.mPackageName, result.mLetterboxDetails); // StatusBarManagerService has a back up of IME token and it's restored here. mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken, @@ -1759,6 +1759,7 @@ public class CentralSurfacesImpl extends CoreStartable implements // activity is exited. if (mKeyguardStateController.isShowing() && !mKeyguardStateController.isKeyguardGoingAway()) { + Log.d(TAG, "Setting occluded = true in #startActivity."); mKeyguardViewMediator.setOccluded(true /* isOccluded */, true /* animate */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java index c61510cce10e..6e98c49e6d43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java @@ -32,6 +32,7 @@ import android.view.animation.AccelerateInterpolator; import androidx.lifecycle.Observer; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; @@ -144,7 +145,7 @@ public class LightsOutNotifController extends ViewController<View> { public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index c757cba31967..648bb0c0b8e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -115,6 +115,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.Interpolators; import com.android.systemui.animation.LaunchAnimator; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.Classifier; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.controls.dagger.ControlsComponent; @@ -694,6 +695,8 @@ public class NotificationPanelViewController extends PanelViewController { } }; + private final CameraGestureHelper mCameraGestureHelper; + @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, @@ -764,7 +767,8 @@ public class NotificationPanelViewController extends PanelViewController { NotificationStackSizeCalculator notificationStackSizeCalculator, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, ShadeTransitionController shadeTransitionController, - SystemClock systemClock) { + SystemClock systemClock, + CameraGestureHelper cameraGestureHelper) { super(view, falsingManager, dozeLog, @@ -948,6 +952,7 @@ public class NotificationPanelViewController extends PanelViewController { } } }); + mCameraGestureHelper = cameraGestureHelper; } @VisibleForTesting @@ -3641,6 +3646,11 @@ public class NotificationPanelViewController extends PanelViewController { /** Launches the camera. */ public void launchCamera(int source) { + if (!isFullyCollapsed()) { + setLaunchingAffordance(true); + } + + mCameraGestureHelper.launchCamera(source); } public void onAffordanceLaunchEnded() { @@ -3667,17 +3677,7 @@ public class NotificationPanelViewController extends PanelViewController { * Whether the camera application can be launched for the camera launch gesture. */ public boolean canCameraGestureBeLaunched() { - return false; - } - - /** - * Return true if the applications with the package name is running in foreground. - * - * @param pkgName application package name. - */ - private boolean isForegroundApp(String pkgName) { - List<ActivityManager.RunningTaskInfo> tasks = mActivityManager.getRunningTasks(1); - return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName()); + return mCameraGestureHelper.canCameraGestureBeLaunched(mBarState); } public boolean hideStatusBarIconsWhenExpanded() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt index 911e750f666e..a6160aaf7756 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt @@ -20,6 +20,7 @@ import android.annotation.IntDef import android.util.Log import androidx.annotation.FloatRange import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.util.Compile import javax.inject.Inject /** @@ -109,8 +110,8 @@ class PanelExpansionStateManager @Inject constructor() { debugLog( "panelExpansionChanged:" + - "start state=${oldState.stateToString()} " + - "end state=${state.stateToString()} " + + "start state=${oldState.panelStateToString()} " + + "end state=${state.panelStateToString()} " + "f=$fraction " + "expanded=$expanded " + "tracking=$tracking" + @@ -126,14 +127,15 @@ class PanelExpansionStateManager @Inject constructor() { /** Updates the panel state if necessary. */ fun updateState(@PanelState state: Int) { - debugLog("update state: ${this.state.stateToString()} -> ${state.stateToString()}") + debugLog( + "update state: ${this.state.panelStateToString()} -> ${state.panelStateToString()}") if (this.state != state) { updateStateInternal(state) } } private fun updateStateInternal(@PanelState state: Int) { - debugLog("go state: ${this.state.stateToString()} -> ${state.stateToString()}") + debugLog("go state: ${this.state.panelStateToString()} -> ${state.panelStateToString()}") this.state = state stateListeners.forEach { it.onPanelStateChanged(state) } } @@ -154,7 +156,7 @@ const val STATE_OPENING = 1 const val STATE_OPEN = 2 @PanelState -private fun Int.stateToString(): String { +fun Int.panelStateToString(): String { return when (this) { STATE_CLOSED -> "CLOSED" STATE_OPENING -> "OPENING" @@ -163,5 +165,5 @@ private fun Int.stateToString(): String { } } -private const val DEBUG = false private val TAG = PanelExpansionStateManager::class.simpleName +private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt index 16f28e7d1a21..1b8afb9ddc1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt @@ -11,6 +11,8 @@ import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent +import com.android.systemui.statusbar.phone.panelstate.PanelState +import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.LargeScreenUtils import java.io.PrintWriter @@ -30,8 +32,9 @@ constructor( private var inSplitShade = false private var splitShadeScrimTransitionDistance = 0 - private var lastExpansionFraction: Float = 0f + private var lastExpansionFraction: Float? = null private var lastExpansionEvent: PanelExpansionChangeEvent? = null + private var currentPanelState: Int? = null init { updateResources() @@ -41,8 +44,8 @@ constructor( updateResources() } }) - dumpManager - .registerDumpable(ScrimShadeTransitionController::class.java.simpleName, this::dump) + dumpManager.registerDumpable( + ScrimShadeTransitionController::class.java.simpleName, this::dump) } private fun updateResources() { @@ -51,21 +54,38 @@ constructor( resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance) } + fun onPanelStateChanged(@PanelState state: Int) { + currentPanelState = state + onStateChanged() + } + fun onPanelExpansionChanged(panelExpansionChangeEvent: PanelExpansionChangeEvent) { - val expansionFraction = calculateScrimExpansionFraction(panelExpansionChangeEvent) + lastExpansionEvent = panelExpansionChangeEvent + onStateChanged() + } + + private fun onStateChanged() { + val expansionEvent = lastExpansionEvent ?: return + val panelState = currentPanelState + val expansionFraction = calculateScrimExpansionFraction(expansionEvent, panelState) scrimController.setRawPanelExpansionFraction(expansionFraction) lastExpansionFraction = expansionFraction - lastExpansionEvent = panelExpansionChangeEvent } - private fun calculateScrimExpansionFraction(expansionEvent: PanelExpansionChangeEvent): Float { - return if (inSplitShade && isScreenUnlocked()) { + private fun calculateScrimExpansionFraction( + expansionEvent: PanelExpansionChangeEvent, + @PanelState panelState: Int? + ): Float { + return if (canUseCustomFraction(panelState)) { constrain(expansionEvent.dragDownPxAmount / splitShadeScrimTransitionDistance, 0f, 1f) } else { expansionEvent.fraction } } + private fun canUseCustomFraction(panelState: Int?) = + inSplitShade && isScreenUnlocked() && panelState == STATE_OPENING + private fun isScreenUnlocked() = statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE @@ -78,9 +98,9 @@ constructor( isScreenUnlocked: ${isScreenUnlocked()} splitShadeScrimTransitionDistance: $splitShadeScrimTransitionDistance State: + currentPanelState: $currentPanelState lastExpansionFraction: $lastExpansionFraction lastExpansionEvent: $lastExpansionEvent - """.trimIndent() - ) + """.trimIndent()) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt index e967d4af19b1..71c61597ff11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt @@ -11,6 +11,7 @@ import com.android.systemui.statusbar.phone.NotificationPanelViewController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager import com.android.systemui.statusbar.phone.panelstate.PanelState +import com.android.systemui.statusbar.phone.panelstate.panelStateToString import com.android.systemui.statusbar.policy.ConfigurationController import java.io.PrintWriter import javax.inject.Inject @@ -34,6 +35,8 @@ constructor( lateinit var qs: QS private var inSplitShade = false + private var currentPanelState: Int? = null + private var lastPanelExpansionChangeEvent: PanelExpansionChangeEvent? = null private val splitShadeOverScroller by lazy { splitShadeOverScrollerFactory.create({ qs }, { notificationStackScrollLayoutController }) @@ -66,10 +69,13 @@ constructor( } private fun onPanelStateChanged(@PanelState state: Int) { + currentPanelState = state shadeOverScroller.onPanelStateChanged(state) + scrimShadeTransitionController.onPanelStateChanged(state) } private fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) { + lastPanelExpansionChangeEvent = event shadeOverScroller.onDragDownAmountChanged(event.dragDownPxAmount) scrimShadeTransitionController.onPanelExpansionChanged(event) } @@ -84,6 +90,8 @@ constructor( """ ShadeTransitionController: inSplitShade: $inSplitShade + currentPanelState: ${currentPanelState?.panelStateToString()} + lastPanelExpansionChangeEvent: $lastPanelExpansionChangeEvent qs.isInitialized: ${this::qs.isInitialized} npvc.isInitialized: ${this::notificationPanelViewController.isInitialized} nssl.isInitialized: ${this::notificationStackScrollLayoutController.isInitialized} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java index 4cf1d2b3f91d..9946b4b9ecaa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java @@ -17,15 +17,11 @@ package com.android.systemui.statusbar.policy; import android.annotation.WorkerThread; -import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Process; import android.provider.Settings; import android.provider.Settings.Secure; import android.text.TextUtils; @@ -33,12 +29,19 @@ import android.util.Log; import androidx.annotation.NonNull; +import com.android.internal.annotations.GuardedBy; +import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dump.DumpManager; +import com.android.systemui.util.settings.SecureSettings; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -59,65 +62,88 @@ public class FlashlightControllerImpl implements FlashlightController { "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED"; private final CameraManager mCameraManager; - private final Context mContext; - /** Call {@link #ensureHandler()} before using */ - private Handler mHandler; + private final Executor mExecutor; + private final SecureSettings mSecureSettings; + private final DumpManager mDumpManager; + private final BroadcastSender mBroadcastSender; - /** Lock on mListeners when accessing */ + private final boolean mHasFlashlight; + + @GuardedBy("mListeners") private final ArrayList<WeakReference<FlashlightListener>> mListeners = new ArrayList<>(1); - /** Lock on {@code this} when accessing */ + @GuardedBy("this") private boolean mFlashlightEnabled; - - private String mCameraId; + @GuardedBy("this") private boolean mTorchAvailable; + private final AtomicReference<String> mCameraId; + private final AtomicBoolean mInitted = new AtomicBoolean(false); + @Inject - public FlashlightControllerImpl(Context context, DumpManager dumpManager) { - mContext = context; - mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); + public FlashlightControllerImpl( + DumpManager dumpManager, + CameraManager cameraManager, + @Background Executor bgExecutor, + SecureSettings secureSettings, + BroadcastSender broadcastSender, + PackageManager packageManager + ) { + mCameraManager = cameraManager; + mExecutor = bgExecutor; + mCameraId = new AtomicReference<>(null); + mSecureSettings = secureSettings; + mDumpManager = dumpManager; + mBroadcastSender = broadcastSender; + + mHasFlashlight = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); + init(); + } - dumpManager.registerDumpable(getClass().getSimpleName(), this); - tryInitCamera(); + private void init() { + if (!mInitted.getAndSet(true)) { + mDumpManager.registerDumpable(getClass().getSimpleName(), this); + mExecutor.execute(this::tryInitCamera); + } } + @WorkerThread private void tryInitCamera() { + if (!mHasFlashlight || mCameraId.get() != null) return; try { - mCameraId = getCameraId(); + mCameraId.set(getCameraId()); } catch (Throwable e) { Log.e(TAG, "Couldn't initialize.", e); return; } - if (mCameraId != null) { - ensureHandler(); - mCameraManager.registerTorchCallback(mTorchCallback, mHandler); + if (mCameraId.get() != null) { + mCameraManager.registerTorchCallback(mExecutor, mTorchCallback); } } public void setFlashlight(boolean enabled) { - boolean pendingError = false; - synchronized (this) { - if (mCameraId == null) return; - if (mFlashlightEnabled != enabled) { - mFlashlightEnabled = enabled; - try { - mCameraManager.setTorchMode(mCameraId, enabled); - } catch (CameraAccessException e) { - Log.e(TAG, "Couldn't set torch mode", e); - mFlashlightEnabled = false; - pendingError = true; + if (!mHasFlashlight) return; + if (mCameraId.get() == null) { + mExecutor.execute(this::tryInitCamera); + } + mExecutor.execute(() -> { + if (mCameraId.get() == null) return; + synchronized (this) { + if (mFlashlightEnabled != enabled) { + try { + mCameraManager.setTorchMode(mCameraId.get(), enabled); + } catch (CameraAccessException e) { + Log.e(TAG, "Couldn't set torch mode", e); + dispatchError(); + } } } - } - dispatchModeChanged(mFlashlightEnabled); - if (pendingError) { - dispatchError(); - } + }); } public boolean hasFlashlight() { - return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); + return mHasFlashlight; } public synchronized boolean isEnabled() { @@ -131,13 +157,13 @@ public class FlashlightControllerImpl implements FlashlightController { @Override public void addCallback(@NonNull FlashlightListener l) { synchronized (mListeners) { - if (mCameraId == null) { - tryInitCamera(); + if (mCameraId.get() == null) { + mExecutor.execute(this::tryInitCamera); } cleanUpListenersLocked(l); mListeners.add(new WeakReference<>(l)); - l.onFlashlightAvailabilityChanged(mTorchAvailable); - l.onFlashlightChanged(mFlashlightEnabled); + l.onFlashlightAvailabilityChanged(isAvailable()); + l.onFlashlightChanged(isEnabled()); } } @@ -148,14 +174,7 @@ public class FlashlightControllerImpl implements FlashlightController { } } - private synchronized void ensureHandler() { - if (mHandler == null) { - HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); - thread.start(); - mHandler = new Handler(thread.getLooper()); - } - } - + @WorkerThread private String getCameraId() throws CameraAccessException { String[] ids = mCameraManager.getCameraIdList(); for (String id : ids) { @@ -221,10 +240,9 @@ public class FlashlightControllerImpl implements FlashlightController { @Override @WorkerThread public void onTorchModeUnavailable(String cameraId) { - if (TextUtils.equals(cameraId, mCameraId)) { + if (TextUtils.equals(cameraId, mCameraId.get())) { setCameraAvailable(false); - Settings.Secure.putInt( - mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 0); + mSecureSettings.putInt(Settings.Secure.FLASHLIGHT_AVAILABLE, 0); } } @@ -232,14 +250,12 @@ public class FlashlightControllerImpl implements FlashlightController { @Override @WorkerThread public void onTorchModeChanged(String cameraId, boolean enabled) { - if (TextUtils.equals(cameraId, mCameraId)) { + if (TextUtils.equals(cameraId, mCameraId.get())) { setCameraAvailable(true); setTorchMode(enabled); - Settings.Secure.putInt( - mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1); - Settings.Secure.putInt( - mContext.getContentResolver(), Secure.FLASHLIGHT_ENABLED, enabled ? 1 : 0); - mContext.sendBroadcast(new Intent(ACTION_FLASHLIGHT_CHANGED)); + mSecureSettings.putInt(Settings.Secure.FLASHLIGHT_AVAILABLE, 1); + mSecureSettings.putInt(Secure.FLASHLIGHT_ENABLED, enabled ? 1 : 0); + mBroadcastSender.sendBroadcast(new Intent(ACTION_FLASHLIGHT_CHANGED)); } } diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java index cc6bf6a70d4e..f01712653e1b 100644 --- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.settingslib.users.EditUserInfoController; import com.android.systemui.R; +import com.android.systemui.plugins.ActivityStarter; import javax.inject.Inject; @@ -55,15 +56,18 @@ public class CreateUserActivity extends Activity { private final UserCreator mUserCreator; private final EditUserInfoController mEditUserInfoController; private final IActivityManager mActivityManager; + private final ActivityStarter mActivityStarter; private Dialog mSetupUserDialog; @Inject public CreateUserActivity(UserCreator userCreator, - EditUserInfoController editUserInfoController, IActivityManager activityManager) { + EditUserInfoController editUserInfoController, IActivityManager activityManager, + ActivityStarter activityStarter) { mUserCreator = userCreator; mEditUserInfoController = editUserInfoController; mActivityManager = activityManager; + mActivityStarter = activityStarter; } @Override @@ -104,10 +108,7 @@ public class CreateUserActivity extends Activity { return mEditUserInfoController.createDialog( this, - (intent, requestCode) -> { - mEditUserInfoController.startingActivityForResult(); - startActivityForResult(intent, requestCode); - }, + this::startActivity, null, defaultUserName, getString(com.android.settingslib.R.string.user_add_user), @@ -160,4 +161,17 @@ public class CreateUserActivity extends Activity { Log.e(TAG, "Couldn't switch user.", e); } } + + /** + * Lambda to start activity from an intent. Ensures that device is unlocked first. + * @param intent + * @param requestCode + */ + private void startActivity(Intent intent, int requestCode) { + mActivityStarter.dismissKeyguardThenExecute(() -> { + mEditUserInfoController.startingActivityForResult(); + startActivityForResult(intent, requestCode); + return true; + }, /* cancel= */ null, /* afterKeyguardGone= */ true); + } } diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java index 4e9030f8045c..dac8a0bff28a 100644 --- a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java @@ -92,7 +92,15 @@ public class Monitor { } private void updateConditionMetState(Condition condition) { - mConditions.get(condition).stream().forEach(token -> mSubscriptions.get(token).update()); + final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition); + + // It's possible the condition was removed between the time the callback occurred and + // update was executed on the main thread. + if (subscriptions == null) { + return; + } + + subscriptions.stream().forEach(token -> mSubscriptions.get(token).update()); } /** diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java index e90775de591a..bca2a24ff12d 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java @@ -21,14 +21,10 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL; -import static android.service.notification.NotificationListenerService.REASON_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; -import static android.service.notification.NotificationListenerService.REASON_CLICK; import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE; import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; -import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; @@ -55,7 +51,6 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; @@ -63,9 +58,7 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationShadeWindowController; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.NotificationChannelHelper; -import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -114,7 +107,6 @@ public class BubblesManager implements Dumpable { private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final NotificationLockscreenUserManager mNotifUserManager; private final NotificationGroupManagerLegacy mNotificationGroupManager; - private final NotificationEntryManager mNotificationEntryManager; private final CommonNotifCollection mCommonNotifCollection; private final NotifPipeline mNotifPipeline; private final Executor mSysuiMainExecutor; @@ -142,11 +134,9 @@ public class BubblesManager implements Dumpable { ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, - NotifPipelineFlags notifPipelineFlags, DumpManager dumpManager, Executor sysuiMainExecutor) { if (bubblesOptional.isPresent()) { @@ -163,11 +153,9 @@ public class BubblesManager implements Dumpable { zenModeController, notifUserManager, groupManager, - entryManager, notifCollection, notifPipeline, sysUiState, - notifPipelineFlags, dumpManager, sysuiMainExecutor); } else { @@ -189,11 +177,9 @@ public class BubblesManager implements Dumpable { ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, - NotifPipelineFlags notifPipelineFlags, DumpManager dumpManager, Executor sysuiMainExecutor) { mContext = context; @@ -205,7 +191,6 @@ public class BubblesManager implements Dumpable { mNotificationInterruptStateProvider = interruptionStateProvider; mNotifUserManager = notifUserManager; mNotificationGroupManager = groupManager; - mNotificationEntryManager = entryManager; mCommonNotifCollection = notifCollection; mNotifPipeline = notifPipeline; mSysuiMainExecutor = sysuiMainExecutor; @@ -215,11 +200,7 @@ public class BubblesManager implements Dumpable { ServiceManager.getService(Context.STATUS_BAR_SERVICE)) : statusBarService; - if (notifPipelineFlags.isNewPipelineEnabled()) { - setupNotifPipeline(); - } else { - setupNEM(); - } + setupNotifPipeline(); dumpManager.registerDumpable(TAG, this); @@ -438,141 +419,6 @@ public class BubblesManager implements Dumpable { mBubbles.setSysuiProxy(mSysuiProxy); } - private void setupNEM() { - mNotificationEntryManager.addNotificationEntryListener( - new NotificationEntryListener() { - @Override - public void onPendingEntryAdded(NotificationEntry entry) { - BubblesManager.this.onEntryAdded(entry); - } - - @Override - public void onPreEntryUpdated(NotificationEntry entry) { - BubblesManager.this.onEntryUpdated(entry); - } - - @Override - public void onEntryRemoved( - NotificationEntry entry, - @Nullable NotificationVisibility visibility, - boolean removedByUser, - int reason) { - BubblesManager.this.onEntryRemoved(entry); - } - - @Override - public void onNotificationRankingUpdated(RankingMap rankingMap) { - BubblesManager.this.onRankingUpdate(rankingMap); - } - - @Override - public void onNotificationChannelModified( - String pkgName, - UserHandle user, - NotificationChannel channel, - int modificationType) { - BubblesManager.this.onNotificationChannelModified(pkgName, - user, - channel, - modificationType); - } - }); - - // The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator - mNotificationEntryManager.addNotificationRemoveInterceptor( - (key, entry, dismissReason) -> { - final boolean isClearAll = dismissReason == REASON_CANCEL_ALL; - final boolean isUserDismiss = dismissReason == REASON_CANCEL - || dismissReason == REASON_CLICK; - final boolean isAppCancel = dismissReason == REASON_APP_CANCEL - || dismissReason == REASON_APP_CANCEL_ALL; - final boolean isSummaryCancel = - dismissReason == REASON_GROUP_SUMMARY_CANCELED; - - // Need to check for !appCancel here because the notification may have - // previously been dismissed & entry.isRowDismissed would still be true - boolean userRemovedNotif = - (entry != null && entry.isRowDismissed() && !isAppCancel) - || isClearAll || isUserDismiss || isSummaryCancel; - - if (userRemovedNotif) { - return handleDismissalInterception(entry); - } - return false; - }); - - mNotificationGroupManager.registerGroupChangeListener( - new NotificationGroupManagerLegacy.OnGroupChangeListener() { - @Override - public void onGroupSuppressionChanged( - NotificationGroupManagerLegacy.NotificationGroup group, - boolean suppressed) { - // More notifications could be added causing summary to no longer - // be suppressed -- in this case need to remove the key. - final String groupKey = group.summary != null - ? group.summary.getSbn().getGroupKey() - : null; - if (!suppressed && groupKey != null) { - mBubbles.removeSuppressedSummaryIfNecessary(groupKey, null, null); - } - } - }); - - addNotifCallback(new NotifCallback() { - @Override - public void removeNotification(NotificationEntry entry, - DismissedByUserStats dismissedByUserStats, int reason) { - mNotificationEntryManager.performRemoveNotification(entry.getSbn(), - dismissedByUserStats, reason); - } - - @Override - public void invalidateNotifications(String reason) { - mNotificationEntryManager.updateNotifications(reason); - } - - @Override - public void maybeCancelSummary(NotificationEntry entry) { - // Check if removed bubble has an associated suppressed group summary that needs - // to be removed now. - final String groupKey = entry.getSbn().getGroupKey(); - mBubbles.removeSuppressedSummaryIfNecessary(groupKey, (summaryKey) -> { - final NotificationEntry summary = - mNotificationEntryManager.getActiveNotificationUnfiltered(summaryKey); - if (summary != null) { - mNotificationEntryManager.performRemoveNotification( - summary.getSbn(), - getDismissedByUserStats(summary, false), - UNDEFINED_DISMISS_REASON); - } - }, mSysuiMainExecutor); - - // Check if we still need to remove the summary from NoManGroup because the summary - // may not be in the mBubbleData.mSuppressedGroupKeys list and removed above. - // For example: - // 1. Bubbled notifications (group) is posted to shade and are visible bubbles - // 2. User expands bubbles so now their respective notifications in the shade are - // hidden, including the group summary - // 3. User removes all bubbles - // 4. We expect all the removed bubbles AND the summary (note: the summary was - // never added to the suppressedSummary list in BubbleData, so we add this check) - NotificationEntry summary = mNotificationGroupManager.getLogicalGroupSummary(entry); - if (summary != null) { - ArrayList<NotificationEntry> summaryChildren = - mNotificationGroupManager.getLogicalChildren(summary.getSbn()); - boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey()); - if (!isSummaryThisNotif && (summaryChildren == null - || summaryChildren.isEmpty())) { - mNotificationEntryManager.performRemoveNotification( - summary.getSbn(), - getDismissedByUserStats(summary, false), - UNDEFINED_DISMISS_REASON); - } - } - } - }); - } - private void setupNotifPipeline() { mNotifPipeline.addCollectionListener(new NotifCollectionListener() { @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index d5df9fe0c2e8..c48cbb19b40a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -159,7 +159,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { @Test fun doesNotStartIfAnimationIsCancelled() { val runner = activityLaunchAnimator.createRunner(controller) - runner.onAnimationCancelled() + runner.onAnimationCancelled(false /* isKeyguardOccluded */) runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback) waitForIdleSync() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt index d0cf792b698d..6978490a1252 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.charging import android.testing.AndroidTestingRunner import android.view.View @@ -24,6 +24,7 @@ import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.ripple.RippleView import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController @@ -50,7 +51,7 @@ class WiredChargingRippleControllerTest : SysuiTestCase() { @Mock private lateinit var batteryController: BatteryController @Mock private lateinit var featureFlags: FeatureFlags @Mock private lateinit var configurationController: ConfigurationController - @Mock private lateinit var rippleView: ChargingRippleView + @Mock private lateinit var rippleView: RippleView @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var uiEventLogger: UiEventLogger private val systemClock = FakeSystemClock() diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt index b97924107322..f56d42ec3fb4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt @@ -16,7 +16,6 @@ package com.android.systemui.media -import org.mockito.Mockito.`when` as whenever import android.animation.ValueAnimator import android.graphics.Color import android.testing.AndroidTestingRunner @@ -34,6 +33,7 @@ import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit private const val DEFAULT_COLOR = Color.RED @@ -147,8 +147,8 @@ class ColorSchemeTransitionTest : SysuiTestCase() { @Test fun testColorSchemeTransition_update() { - colorSchemeTransition.updateColorScheme(colorScheme, true) - verify(mockAnimatingTransition, times(10)).updateColorScheme(colorScheme) + colorSchemeTransition.updateColorScheme(colorScheme) + verify(mockAnimatingTransition, times(8)).updateColorScheme(colorScheme) verify(gutsViewHolder).colorScheme = colorScheme } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index 540f2a534854..c13c30baed0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -21,7 +21,6 @@ import android.animation.AnimatorSet import android.app.PendingIntent import android.app.smartspace.SmartspaceAction import android.content.Context -import org.mockito.Mockito.`when` as whenever import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager @@ -69,8 +68,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.KotlinArgumentCaptor -import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.nullable import com.android.systemui.util.mockito.withArgCaptor @@ -93,6 +92,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit private const val KEY = "TEST_KEY" @@ -355,6 +355,7 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(viewHolder.player).thenReturn(view) whenever(viewHolder.appIcon).thenReturn(appIcon) whenever(viewHolder.albumView).thenReturn(albumView) + whenever(albumView.foreground).thenReturn(mock(Drawable::class.java)) whenever(viewHolder.titleText).thenReturn(titleText) whenever(viewHolder.artistText).thenReturn(artistText) whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt index 1527f0d0d71f..2eb478303cb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt @@ -371,11 +371,9 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() { powerManager, R.layout.media_ttt_chip ) { - override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) { - - } - - override fun getIconSize(isAppIcon: Boolean): Int? = ICON_SIZE + override val windowLayoutParams = commonWindowLayoutParams + override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) {} + override fun getIconSize(isAppIcon: Boolean): Int = ICON_SIZE } inner class ChipInfo : ChipInfoCommon { @@ -386,4 +384,4 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() { private const val PACKAGE_NAME = "com.android.systemui" private const val APP_NAME = "Fake App Name" private const val TIMEOUT_MS = 10000L -private const val ICON_SIZE = 47
\ No newline at end of file +private const val ICON_SIZE = 47 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index fc4d9c42eb49..cf7f8dd26647 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -41,6 +41,7 @@ import android.view.WindowInsetsController.Behavior; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.view.AppearanceRegion; import com.android.systemui.SysuiTestCase; @@ -53,6 +54,13 @@ import org.junit.Test; @SmallTest public class CommandQueueTest extends SysuiTestCase { + private static final LetterboxDetails[] TEST_LETTERBOX_DETAILS = new LetterboxDetails[] { + new LetterboxDetails( + /* letterboxInnerBounds= */ new Rect(100, 0, 200, 500), + /* letterboxFullBounds= */ new Rect(0, 0, 500, 100), + /* appAppearance= */ 123) + }; + private CommandQueue mCommandQueue; private Callbacks mCallbacks; private static final int SECONDARY_DISPLAY = 1; @@ -127,25 +135,27 @@ public class CommandQueueTest extends SysuiTestCase { public void testOnSystemBarAttributesChanged() { doTestOnSystemBarAttributesChanged(DEFAULT_DISPLAY, 1, new AppearanceRegion[]{new AppearanceRegion(2, new Rect())}, false, - BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test"); + BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test", TEST_LETTERBOX_DETAILS); } @Test public void testOnSystemBarAttributesChangedForSecondaryDisplay() { doTestOnSystemBarAttributesChanged(SECONDARY_DISPLAY, 1, new AppearanceRegion[]{new AppearanceRegion(2, new Rect())}, false, - BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test"); + BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test", TEST_LETTERBOX_DETAILS); } private void doTestOnSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { mCommandQueue.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); waitForIdleSync(); verify(mCallbacks).onSystemBarAttributesChanged(eq(displayId), eq(appearance), eq(appearanceRegions), eq(navbarColorManagedByIme), eq(behavior), - eq(requestedVisibilities), eq(packageName)); + eq(requestedVisibilities), eq(packageName), eq(letterboxDetails)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java index f286349971d2..af43826091a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java @@ -1684,9 +1684,9 @@ public class NotifCollectionTest extends SysuiTestCase { return new CollectionEvent(rawEvent, requireNonNull(mEntryCaptor.getValue())); } - private void verifyBuiltList(Collection<NotificationEntry> list) { - verify(mBuildListener).onBuildList(mBuildListCaptor.capture()); - assertEquals(new ArraySet<>(list), new ArraySet<>(mBuildListCaptor.getValue())); + private void verifyBuiltList(Collection<NotificationEntry> expectedList) { + verify(mBuildListener).onBuildList(mBuildListCaptor.capture(), any()); + assertThat(mBuildListCaptor.getValue()).containsExactly(expectedList.toArray()); } private static class RecordingCollectionListener implements NotifCollectionListener { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java index 95460583e857..555adfdfdc31 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java @@ -570,7 +570,7 @@ public class ShadeListBuilderTest extends SysuiTestCase { assertTrue(entry.hasFinishedInitialization()); // WHEN the pipeline is kicked off - mReadyForBuildListener.onBuildList(singletonList(entry)); + mReadyForBuildListener.onBuildList(singletonList(entry), "test"); mPipelineChoreographer.runIfScheduled(); // THEN the entry's initialization time is reset @@ -2092,7 +2092,7 @@ public class ShadeListBuilderTest extends SysuiTestCase { mPendingSet.clear(); } - mReadyForBuildListener.onBuildList(mEntrySet); + mReadyForBuildListener.onBuildList(mEntrySet, "test"); mPipelineChoreographer.runIfScheduled(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index 275dbfd516e4..8fd6842911de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -15,6 +15,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue +import junit.framework.Assert.assertEquals import org.junit.Before import org.junit.Test import org.mockito.Mockito.mock @@ -164,4 +165,178 @@ class StackScrollAlgorithmTest : SysuiTestCase() { stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) } + + @Test + fun maybeUpdateHeadsUpIsVisible_endVisible_true() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = false + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 0f, + /* maxHunY= */ 10f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_endHidden_false() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 0f) + + assertFalse(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_shadeClosed_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ false, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_notHUN_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ false, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_topHidden_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ false, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun clampHunToTop_viewYGreaterThanQqs_viewYUnchanged() { + val expandableViewState = ExpandableViewState() + expandableViewState.yTranslation = 50f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 1f, expandableViewState) + + // qqs (10 + 0) < viewY (50) + assertEquals(50f, expandableViewState.yTranslation) + } + + @Test + fun clampHunToTop_viewYLessThanQqs_viewYChanged() { + val expandableViewState = ExpandableViewState() + expandableViewState.yTranslation = -10f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 1f, expandableViewState) + + // qqs (10 + 0) > viewY (-10) + assertEquals(10f, expandableViewState.yTranslation) + } + + + @Test + fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() { + val expandableViewState = ExpandableViewState() + expandableViewState.height = 20 + expandableViewState.yTranslation = -100f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 10f, expandableViewState) + + // newTranslation = max(10, -100) = 10 + // distToRealY = 10 - (-100f) = 110 + // height = max(20 - 110, 10f) + assertEquals(10, expandableViewState.height) + } + + @Test + fun clampHunToTop_viewYNearVisibleStack_heightTallerThanCollapsed() { + val expandableViewState = ExpandableViewState() + expandableViewState.height = 20 + expandableViewState.yTranslation = 5f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 10f, expandableViewState) + + // newTranslation = max(10, 5) = 10 + // distToRealY = 10 - 5 = 5 + // height = max(20 - 5, 10) = 15 + assertEquals(15, expandableViewState.height) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackBelowScreen_round() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 110f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(1f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackAboveScreenBelowPinPoint_halfRound() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 90f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(0.5f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackAbovePinPoint_notRound() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 0f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(0f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_originallyRoundAndStackAbovePinPoint_round() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 0f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 1f) + assertEquals(1f, currentRoundness) + } } 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 e5b6286fcd7c..272ef3ddc64e 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 @@ -131,6 +131,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { when(mKeyguardBypassController.onBiometricAuthenticated(any(), anyBoolean())) .thenReturn(true); when(mAuthController.isUdfpsFingerDown()).thenReturn(false); + when(mVibratorHelper.hasVibrator()).thenReturn(true); mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager); mBiometricUnlockController = new BiometricUnlockController(mDozeScrimController, mKeyguardViewMediator, mScrimController, mShadeController, @@ -423,4 +424,35 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { verify(mHandler).post(captor.capture()); captor.getValue().run(); } + + @Test + public void onFPFailureNoHaptics_notDeviceInteractive_showBouncer() { + // GIVEN no vibrator and the screen is off + when(mVibratorHelper.hasVibrator()).thenReturn(false); + when(mUpdateMonitor.isDeviceInteractive()).thenReturn(false); + when(mUpdateMonitor.isDreaming()).thenReturn(false); + + // WHEN FP fails + mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); + + // after device is finished waking up + mBiometricUnlockController.mWakefulnessObserver.onFinishedWakingUp(); + + // THEN show the bouncer + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } + + @Test + public void onFPFailureNoHaptics_dreaming_showBouncer() { + // GIVEN no vibrator and device is dreaming + when(mVibratorHelper.hasVibrator()).thenReturn(false); + when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true); + when(mUpdateMonitor.isDreaming()).thenReturn(true); + + // WHEN FP fails + mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); + + // THEN show the bouncer + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } } 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 266f0e95f2ce..2e26a2be4382 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 @@ -84,6 +84,7 @@ import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenu import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.charging.WiredChargingRippleController; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -117,7 +118,6 @@ import com.android.systemui.statusbar.OperatorNameViewController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; -import com.android.systemui.statusbar.charging.WiredChargingRippleController; import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java index 9664035e1e1b..fca9771648ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java @@ -108,7 +108,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); assertTrue(mLightsOutNotifController.areLightsOut()); } @@ -121,7 +122,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); assertFalse(mLightsOutNotifController.areLightsOut()); } @@ -152,7 +154,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we should show dot assertTrue(mLightsOutNotifController.shouldShowDot()); @@ -172,7 +175,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we shouldn't show the dot assertFalse(mLightsOutNotifController.shouldShowDot()); @@ -192,7 +196,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we shouldn't show the dot assertFalse(mLightsOutNotifController.shouldShowDot()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 046af95c8c1d..686718a96dd2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -87,6 +87,7 @@ import com.android.systemui.DejankUtils; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.controls.dagger.ControlsComponent; @@ -541,7 +542,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mNotificationStackSizeCalculator, mUnlockedScreenOffAnimationController, mShadeTransitionController, - mSystemClock); + mSystemClock, + mock(CameraGestureHelper.class)); mNotificationPanelViewController.initDependencies( mCentralSurfaces, () -> {}, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt index cafe113e7872..304a274576b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt @@ -9,6 +9,9 @@ import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent +import com.android.systemui.statusbar.phone.panelstate.STATE_CLOSED +import com.android.systemui.statusbar.phone.panelstate.STATE_OPEN +import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING import com.android.systemui.statusbar.policy.FakeConfigurationController import org.junit.Before import org.junit.Test @@ -39,8 +42,9 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { dumpManager, scrimController, context.resources, - statusBarStateController - ) + statusBarStateController) + + controller.onPanelStateChanged(STATE_OPENING) } @Test @@ -54,8 +58,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { @Test fun onPanelExpansionChanged_inSplitShade_unlockedShade_setsFractionBasedOnDragDownAmount() { - whenever(statusBarStateController.currentOrUpcomingState) - .thenReturn(StatusBarState.SHADE) + whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE) val scrimShadeTransitionDistance = context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance) setSplitShadeEnabled(true) @@ -68,23 +71,20 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { @Test fun onPanelExpansionChanged_inSplitShade_largeDragDownAmount_fractionIsNotGreaterThan1() { - whenever(statusBarStateController.currentOrUpcomingState) - .thenReturn(StatusBarState.SHADE) + whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE) val scrimShadeTransitionDistance = context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance) setSplitShadeEnabled(true) controller.onPanelExpansionChanged( - EXPANSION_EVENT.copy(dragDownPxAmount = 100f * scrimShadeTransitionDistance) - ) + EXPANSION_EVENT.copy(dragDownPxAmount = 100f * scrimShadeTransitionDistance)) verify(scrimController).setRawPanelExpansionFraction(1f) } @Test fun onPanelExpansionChanged_inSplitShade_negativeDragDownAmount_fractionIsNotLessThan0() { - whenever(statusBarStateController.currentOrUpcomingState) - .thenReturn(StatusBarState.SHADE) + whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE) setSplitShadeEnabled(true) controller.onPanelExpansionChanged(EXPANSION_EVENT.copy(dragDownPxAmount = -100f)) @@ -114,6 +114,30 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction) } + @Test + fun onPanelExpansionChanged_inSplitShade_panelOpen_setsFractionEqualToEventFraction() { + controller.onPanelStateChanged(STATE_OPEN) + whenever(statusBarStateController.currentOrUpcomingState) + .thenReturn(StatusBarState.KEYGUARD) + setSplitShadeEnabled(true) + + controller.onPanelExpansionChanged(EXPANSION_EVENT) + + verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction) + } + + @Test + fun onPanelExpansionChanged_inSplitShade_panelClosed_setsFractionEqualToEventFraction() { + controller.onPanelStateChanged(STATE_CLOSED) + whenever(statusBarStateController.currentOrUpcomingState) + .thenReturn(StatusBarState.KEYGUARD) + setSplitShadeEnabled(true) + + controller.onPanelExpansionChanged(EXPANSION_EVENT) + + verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction) + } + private fun setSplitShadeEnabled(enabled: Boolean) { overrideResource(R.bool.config_use_split_notification_shade, enabled) configurationController.notifyConfigurationChanged() @@ -122,7 +146,6 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { companion object { val EXPANSION_EVENT = PanelExpansionChangeEvent( - fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 10f - ) + fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 10f) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt index 85a8c6bf7d95..8b7e04bbab1b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt @@ -8,6 +8,7 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.phone.NotificationPanelViewController +import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING import com.android.systemui.statusbar.policy.FakeConfigurationController @@ -49,8 +50,7 @@ class ShadeTransitionControllerTest : SysuiTestCase() { context, splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller }, noOpOverScroller, - scrimShadeTransitionController - ) + scrimShadeTransitionController) // Resetting as they are notified upon initialization. reset(noOpOverScroller, splitShadeOverScroller) @@ -91,6 +91,16 @@ class ShadeTransitionControllerTest : SysuiTestCase() { verifyZeroInteractions(splitShadeOverScroller) } + @Test + fun onPanelStateChanged_forwardsToScrimTransitionController() { + initLateProperties() + + startPanelExpansion() + + verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING) + verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT) + } + private fun initLateProperties() { controller.qs = qs controller.notificationStackScrollLayoutController = nsslController @@ -112,14 +122,20 @@ class ShadeTransitionControllerTest : SysuiTestCase() { private fun startPanelExpansion() { panelExpansionStateManager.onPanelExpansionChanged( - fraction = 0.5f, - expanded = true, - tracking = true, - dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT + DEFAULT_EXPANSION_EVENT.fraction, + DEFAULT_EXPANSION_EVENT.expanded, + DEFAULT_EXPANSION_EVENT.tracking, + DEFAULT_EXPANSION_EVENT.dragDownPxAmount, ) } companion object { private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f + private val DEFAULT_EXPANSION_EVENT = + PanelExpansionChangeEvent( + fraction = 0.5f, + expanded = true, + tracking = true, + dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt new file mode 100644 index 000000000000..db0029af4ee2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt @@ -0,0 +1,144 @@ +/* + * 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.systemui.statusbar.policy + +import android.content.pm.PackageManager +import android.hardware.camera2.CameraCharacteristics +import android.hardware.camera2.CameraManager +import android.hardware.camera2.impl.CameraMetadataNative +import android.test.suitebuilder.annotation.SmallTest +import android.testing.AndroidTestingRunner +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.time.FakeSystemClock +import java.util.concurrent.Executor +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.any +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.eq +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class FlashlightControllerImplTest : SysuiTestCase() { + + @Mock + private lateinit var dumpManager: DumpManager + + @Mock + private lateinit var cameraManager: CameraManager + + @Mock + private lateinit var broadcastSender: BroadcastSender + + @Mock + private lateinit var packageManager: PackageManager + + private lateinit var fakeSettings: FakeSettings + private lateinit var fakeSystemClock: FakeSystemClock + private lateinit var backgroundExecutor: FakeExecutor + private lateinit var controller: FlashlightControllerImpl + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + fakeSystemClock = FakeSystemClock() + backgroundExecutor = FakeExecutor(fakeSystemClock) + fakeSettings = FakeSettings() + + `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) + .thenReturn(true) + + controller = FlashlightControllerImpl( + dumpManager, + cameraManager, + backgroundExecutor, + fakeSettings, + broadcastSender, + packageManager + ) + } + + @Test + fun testNoCameraManagerInteractionDirectlyOnConstructor() { + verifyZeroInteractions(cameraManager) + } + + @Test + fun testCameraManagerInitAfterConstructionOnExecutor() { + injectCamera() + backgroundExecutor.runAllReady() + + verify(cameraManager).registerTorchCallback(eq(backgroundExecutor), any()) + } + + @Test + fun testNoCallbackIfNoFlashCamera() { + injectCamera(flash = false) + backgroundExecutor.runAllReady() + + verify(cameraManager, never()).registerTorchCallback(any<Executor>(), any()) + } + + @Test + fun testNoCallbackIfNoBackCamera() { + injectCamera(facing = CameraCharacteristics.LENS_FACING_FRONT) + backgroundExecutor.runAllReady() + + verify(cameraManager, never()).registerTorchCallback(any<Executor>(), any()) + } + + @Test + fun testSetFlashlightInBackgroundExecutor() { + val id = injectCamera() + backgroundExecutor.runAllReady() + + clearInvocations(cameraManager) + val enable = !controller.isEnabled + controller.setFlashlight(enable) + verifyNoMoreInteractions(cameraManager) + + backgroundExecutor.runAllReady() + verify(cameraManager).setTorchMode(id, enable) + } + + private fun injectCamera( + flash: Boolean = true, + facing: Int = CameraCharacteristics.LENS_FACING_BACK + ): String { + val cameraID = "ID" + val camera = CameraCharacteristics(CameraMetadataNative().apply { + set(CameraCharacteristics.FLASH_INFO_AVAILABLE, flash) + set(CameraCharacteristics.LENS_FACING, facing) + }) + `when`(cameraManager.cameraIdList).thenReturn(arrayOf(cameraID)) + `when`(cameraManager.getCameraCharacteristics(cameraID)).thenReturn(camera) + return cameraID + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java index 1e35b0f0e68a..125b3627b342 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java @@ -159,6 +159,24 @@ public class ConditionMonitorTest extends SysuiTestCase { Mockito.clearInvocations(callback); } + // Ensure that updating a callback that is removed doesn't result in an exception due to the + // absence of the condition. + @Test + public void testUpdateRemovedCallback() { + final Monitor.Callback callback1 = + mock(Monitor.Callback.class); + final Monitor.Subscription.Token subscription1 = + mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build()); + ArgumentCaptor<Condition.Callback> monitorCallback = + ArgumentCaptor.forClass(Condition.Callback.class); + mExecutor.runAllReady(); + verify(mCondition1).addCallback(monitorCallback.capture()); + // This will execute first before the handler for onConditionChanged. + mConditionMonitor.removeSubscription(subscription1); + monitorCallback.getValue().onConditionChanged(mCondition1); + mExecutor.runAllReady(); + } + @Test public void addCallback_addFirstCallback_addCallbackToAllConditions() { final Monitor.Callback callback1 = diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 7d4e27fa2580..2e58fc4f93fa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,9 @@ import static android.app.PendingIntent.FLAG_MUTABLE; import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED; import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NOTIF_CANCEL; import static com.google.common.truth.Truth.assertThat; @@ -62,7 +59,6 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.hardware.display.AmbientDisplayConfiguration; -import android.hardware.face.FaceManager; import android.os.Handler; import android.os.PowerManager; import android.os.UserHandle; @@ -90,18 +86,16 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationRemoveInterceptor; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger; @@ -118,7 +112,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; import com.android.wm.shell.WindowManagerShellWrapper; @@ -140,8 +133,6 @@ import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; -import com.google.common.collect.ImmutableList; - import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -155,22 +146,17 @@ import java.util.HashMap; import java.util.List; import java.util.Optional; -/** - * Tests the NotificationEntryManager setup with BubbleController. - * The {@link NotifPipeline} setup with BubbleController is tested in - * {@link NewNotifPipelineBubblesTest}. - */ @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) public class BubblesTest extends SysuiTestCase { @Mock - private NotificationEntryManager mNotificationEntryManager; - @Mock private CommonNotifCollection mCommonNotifCollection; @Mock private NotificationGroupManagerLegacy mNotificationGroupManager; @Mock + private BubblesManager.NotifCallback mNotifCallback; + @Mock private WindowManager mWindowManager; @Mock private IActivityManager mActivityManager; @@ -183,8 +169,6 @@ public class BubblesTest extends SysuiTestCase { @Mock private ZenModeConfig mZenModeConfig; @Mock - private FaceManager mFaceManager; - @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private SysuiStatusBarStateController mStatusBarStateController; @@ -196,15 +180,17 @@ public class BubblesTest extends SysuiTestCase { private FloatingContentCoordinator mFloatingContentCoordinator; @Mock private BubbleDataRepository mDataRepository; + @Mock + private NotificationShadeWindowView mNotificationShadeWindowView; + @Mock + private AuthController mAuthController; private SysUiState mSysUiState; private boolean mSysUiStateBubblesExpanded; private boolean mSysUiStateBubblesManageMenuExpanded; @Captor - private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor; - @Captor - private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor; + private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor; @Captor private ArgumentCaptor<List<Bubble>> mBubbleListCaptor; @Captor @@ -212,22 +198,16 @@ public class BubblesTest extends SysuiTestCase { @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor; - private BubblesManager mBubblesManager; - // TODO(178618782): Move tests on the controller directly to the shell private TestableBubbleController mBubbleController; private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; - private NotificationEntryListener mEntryListener; - private NotificationRemoveInterceptor mRemoveInterceptor; - + private NotifCollectionListener mEntryListener; private NotificationTestHelper mNotificationTestHelper; private NotificationEntry mRow; private NotificationEntry mRow2; - private NotificationEntry mRow3; private ExpandableNotificationRow mNonBubbleNotifRow; private BubbleEntry mBubbleEntry; private BubbleEntry mBubbleEntry2; - private BubbleEntry mBubbleEntry3; private BubbleEntry mBubbleEntryUser11; private BubbleEntry mBubbleEntry2User11; @@ -245,12 +225,8 @@ public class BubblesTest extends SysuiTestCase { @Mock private NotifPipeline mNotifPipeline; @Mock - private NotifPipelineFlags mNotifPipelineFlags; - @Mock private DumpManager mDumpManager; @Mock - private NotificationShadeWindowView mNotificationShadeWindowView; - @Mock private IStatusBarService mStatusBarService; @Mock private NotificationVisibilityProvider mVisibilityProvider; @@ -269,8 +245,6 @@ public class BubblesTest extends SysuiTestCase { @Mock private ScreenOffAnimationController mScreenOffAnimationController; @Mock - private AuthController mAuthController; - @Mock private TaskViewTransitions mTaskViewTransitions; @Mock private Optional<OneHandedController> mOneHandedOptional; @@ -290,7 +264,6 @@ public class BubblesTest extends SysuiTestCase { // For the purposes of this test, just run everything synchronously ShellExecutor syncExecutor = new SyncExecutor(); - mContext.addMockSystemService(FaceManager.class, mFaceManager); when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, @@ -308,11 +281,9 @@ public class BubblesTest extends SysuiTestCase { TestableLooper.get(this)); mRow = mNotificationTestHelper.createBubble(mDeleteIntent); mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent); - mRow3 = mNotificationTestHelper.createBubble(mDeleteIntent); mNonBubbleNotifRow = mNotificationTestHelper.createRow(); mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow); mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2); - mBubbleEntry3 = BubblesManager.notifToBubbleEntry(mRow3); UserHandle handle = mock(UserHandle.class); when(handle.getIdentifier()).thenReturn(11); @@ -321,9 +292,6 @@ public class BubblesTest extends SysuiTestCase { mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry( mNotificationTestHelper.createBubble(handle)); - // Return non-null notification data from the CommonNotifCollection - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - mZenModeConfig.suppressedVisualEffects = 0; when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); @@ -336,7 +304,6 @@ public class BubblesTest extends SysuiTestCase { (sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0; }); - // TODO: Fix mPositioner = new TestableBubblePositioner(mContext, mWindowManager); mPositioner.setMaxBubbles(5); mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor); @@ -355,8 +322,6 @@ public class BubblesTest extends SysuiTestCase { mock(NotifPipelineFlags.class), mock(KeyguardNotificationVisibilityProvider.class) ); - - when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false); when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor); mBubbleController = new TestableBubbleController( mContext, @@ -396,23 +361,17 @@ public class BubblesTest extends SysuiTestCase { mZenModeController, mLockscreenUserManager, mNotificationGroupManager, - mNotificationEntryManager, mCommonNotifCollection, mNotifPipeline, mSysUiState, - mNotifPipelineFlags, mDumpManager, syncExecutor); + mBubblesManager.addNotifCallback(mNotifCallback); - // XXX: Does *this* need to be changed? // Get a reference to the BubbleController's entry listener - verify(mNotificationEntryManager, atLeastOnce()) - .addNotificationEntryListener(mEntryListenerCaptor.capture()); - mEntryListener = mEntryListenerCaptor.getValue(); - // And the remove interceptor - verify(mNotificationEntryManager, atLeastOnce()) - .addNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture()); - mRemoveInterceptor = mRemoveInterceptorCaptor.getValue(); + verify(mNotifPipeline, atLeastOnce()) + .addCollectionListener(mNotifListenerCaptor.capture()); + mEntryListener = mNotifListenerCaptor.getValue(); } @Test @@ -433,90 +392,75 @@ public class BubblesTest extends SysuiTestCase { @Test public void testRemoveBubble() { mBubbleController.updateBubble(mBubbleEntry); - assertNotNull(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey())); + assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); assertTrue(mBubbleController.hasBubbles()); - verify(mNotificationEntryManager).updateNotifications(any()); + verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); mBubbleController.removeBubble( mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - verify(mNotificationEntryManager, times(2)).updateNotifications(anyString()); + verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); } @Test - public void testPromoteBubble_autoExpand() throws Exception { - mBubbleController.updateBubble(mBubbleEntry2); + public void testRemoveBubble_withDismissedNotif_inOverflow() { + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2); - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - - Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getKey()); - assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b)); - verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(mRow.getSbn()), any(), anyInt()); - assertThat(mRow.isBubble()).isFalse(); - - Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getKey()); - assertThat(mBubbleData.getSelectedBubble()).isEqualTo(b2); - mBubbleController.promoteBubbleFromOverflow(b); + assertTrue(mBubbleController.hasBubbles()); + assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - assertThat(b.isBubble()).isTrue(); - assertThat(b.shouldAutoExpand()).isTrue(); - int flags = Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE - | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; - verify(mStatusBarService, times(1)).onNotificationBubbleChanged( - eq(b.getKey()), eq(true), eq(flags)); - } + // Make it look like dismissed notif + mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true); - @Test - public void testCancelOverflowBubble() { - mBubbleController.updateBubble(mBubbleEntry2); - mBubbleController.updateBubble(mBubbleEntry, /* suppressFlyout */ - false, /* showInShade */ true); - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2); + // Now remove the bubble mBubbleController.removeBubble( mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); + assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())); - mBubbleController.removeBubble( - mRow.getKey(), DISMISS_NOTIF_CANCEL); - verify(mNotificationEntryManager, times(1)).performRemoveNotification( - eq(mRow.getSbn()), any(), anyInt()); - assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); - assertFalse(mRow.isBubble()); + // We don't remove the notification since the bubble is still in overflow. + verify(mNotifCallback, never()).removeNotification(eq(mRow), any(), anyInt()); + assertFalse(mBubbleController.hasBubbles()); } @Test - public void testUserChange_doesNotRemoveNotif() { + public void testRemoveBubble_withDismissedNotif_notInOverflow() { + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); + when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); + assertTrue(mBubbleController.hasBubbles()); + assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); + // Make it look like dismissed notif + mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true); + + // Now remove the bubble mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_CHANGED); - verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(mRow.getSbn()), any(), anyInt()); + mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); + assertFalse(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())); + + // Since the notif is dismissed and not in overflow, once the bubble is removed, + // removeNotification gets called to really remove the notif + verify(mNotifCallback, times(1)).removeNotification(eq(mRow), + any(), anyInt()); assertFalse(mBubbleController.hasBubbles()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - assertTrue(mRow.isBubble()); } @Test public void testDismissStack() { mBubbleController.updateBubble(mBubbleEntry); - verify(mNotificationEntryManager, times(1)).updateNotifications(any()); + verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); mBubbleController.updateBubble(mBubbleEntry2); - verify(mNotificationEntryManager, times(2)).updateNotifications(any()); + verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey())); assertTrue(mBubbleController.hasBubbles()); mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - verify(mNotificationEntryManager, times(3)).updateNotifications(any()); + verify(mNotifCallback, times(3)).invalidateNotifications(anyString()); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey())); @@ -528,7 +472,7 @@ public class BubblesTest extends SysuiTestCase { assertStackCollapsed(); // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed @@ -536,7 +480,6 @@ public class BubblesTest extends SysuiTestCase { assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); // Expand the stack - BubbleStackView stackView = mBubbleController.getStackView(); mBubbleData.setExpanded(true); assertStackExpanded(); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); @@ -556,8 +499,8 @@ public class BubblesTest extends SysuiTestCase { @Ignore("Currently broken.") public void testCollapseAfterChangingExpandedBubble() { // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); - mEntryListener.onPendingEntryAdded(mRow2); + mEntryListener.onEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow2); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.updateBubble(mBubbleEntry2); @@ -593,6 +536,7 @@ public class BubblesTest extends SysuiTestCase { verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( true, mRow.getKey()); + // Collapse mBubbleController.collapseStack(); assertStackCollapsed(); @@ -602,7 +546,7 @@ public class BubblesTest extends SysuiTestCase { @Test public void testExpansionRemovesShowInShadeAndDot() { // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed @@ -627,7 +571,7 @@ public class BubblesTest extends SysuiTestCase { @Test public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() { // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed @@ -649,7 +593,7 @@ public class BubblesTest extends SysuiTestCase { assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); // Send update - mEntryListener.onPreEntryUpdated(mRow); + mEntryListener.onEntryUpdated(mRow); // Nothing should have changed // Notif is suppressed after expansion @@ -661,8 +605,8 @@ public class BubblesTest extends SysuiTestCase { @Test public void testRemoveLastExpanded_collapses() { // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); - mEntryListener.onPendingEntryAdded(mRow2); + mEntryListener.onEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow2); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.updateBubble(mBubbleEntry2); @@ -707,7 +651,7 @@ public class BubblesTest extends SysuiTestCase { @Test public void testRemoveLastExpandedEmptyOverflow_collapses() { // Mark it as a bubble and add it explicitly - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // Expand @@ -732,6 +676,7 @@ public class BubblesTest extends SysuiTestCase { assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); } + @Test public void testAutoExpand_fails_noFlag() { assertStackCollapsed(); @@ -739,7 +684,7 @@ public class BubblesTest extends SysuiTestCase { Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */); // Add the auto expand bubble - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // Expansion shouldn't change @@ -755,7 +700,7 @@ public class BubblesTest extends SysuiTestCase { Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */); // Add the auto expand bubble - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // Expansion should change @@ -771,7 +716,7 @@ public class BubblesTest extends SysuiTestCase { Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */); // Add the suppress notif bubble - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); // Notif should be suppressed because we were foreground @@ -805,22 +750,8 @@ public class BubblesTest extends SysuiTestCase { } @Test - public void testExpandStackAndSelectBubble_removedFirst() { - mEntryListener.onPendingEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // Simulate notification cancellation. - mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_APP_CANCEL); - - mBubbleController.expandStackAndSelectBubble(mBubbleEntry); - - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test public void testMarkNewNotificationAsShowInShade() { - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); mTestableLooper.processAllMessages(); @@ -829,8 +760,8 @@ public class BubblesTest extends SysuiTestCase { @Test public void testAddNotif_notBubble() { - mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry()); - mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry()); + mEntryListener.onEntryAdded(mNonBubbleNotifRow.getEntry()); + mEntryListener.onEntryUpdated(mNonBubbleNotifRow.getEntry()); assertThat(mBubbleController.hasBubbles()).isFalse(); } @@ -868,48 +799,33 @@ public class BubblesTest extends SysuiTestCase { NotificationListenerService.Ranking ranking = new RankingBuilder( mRow.getRanking()).setCanBubble(false).build(); mRow.setRanking(ranking); - mEntryListener.onPreEntryUpdated(mRow); + mEntryListener.onEntryUpdated(mRow); assertFalse(mBubbleController.hasBubbles()); verify(mDeleteIntent, never()).send(); } @Test - public void testRemoveBubble_succeeds_appCancel() { - mEntryListener.onPendingEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - - boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_APP_CANCEL); - - // Cancels always remove so no need to intercept - assertFalse(intercepted); - } - - @Test public void testRemoveBubble_entryListenerRemove() { - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); // Removes the notification - mEntryListener.onEntryRemoved(mRow, null, false, REASON_APP_CANCEL); + mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL); assertFalse(mBubbleController.hasBubbles()); } @Test - public void removeBubble_clearAllIntercepted() { - mEntryListener.onPendingEntryAdded(mRow); + public void removeBubble_intercepted() { + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_CANCEL_ALL); + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); // Intercept! assertTrue(intercepted); @@ -918,99 +834,51 @@ public class BubblesTest extends SysuiTestCase { } @Test - public void removeBubble_userDismissNotifIntercepted() { - mEntryListener.onPendingEntryAdded(mRow); + public void removeBubble_dismissIntoOverflow_intercepted() { + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_CANCEL); - - // Intercept! - assertTrue(intercepted); - // Should update show in shade state - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - } - - @Test - public void removeNotif_inOverflow_intercepted() { - // Get bubble with notif in shade. - mEntryListener.onPendingEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Dismiss the bubble into overflow. - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); + // Dismiss the bubble + mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertFalse(mBubbleController.hasBubbles()); - boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_CANCEL); + // Dismiss the notification + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); - // Notif is no longer a bubble, but still in overflow, so we intercept removal. + // Intercept dismissal since bubble is going into overflow assertTrue(intercepted); } @Test - public void removeNotif_notInOverflow_notIntercepted() { - // Get bubble with notif in shade. - mEntryListener.onPendingEntryAdded(mRow); + public void removeBubble_notIntercepted() { + mEntryListener.onEntryAdded(mRow); mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_NO_LONGER_BUBBLE); + // Dismiss the bubble + mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertFalse(mBubbleController.hasBubbles()); - boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_CANCEL); + // Dismiss the notification + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); - // Notif is no longer a bubble, so we should not intercept removal. + // Not a bubble anymore so we don't intercept dismissal. assertFalse(intercepted); } @Test - public void testOverflowBubble_maxReached_notInShade_bubbleRemoved() { - mBubbleController.updateBubble( - mBubbleEntry, /* suppressFlyout */ false, /* showInShade */ false); - mBubbleController.updateBubble( - mBubbleEntry2, /* suppressFlyout */ false, /* showInShade */ false); - mBubbleController.updateBubble( - mBubbleEntry3, /* suppressFlyout */ false, /* showInShade */ false); - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2); - when(mCommonNotifCollection.getEntry(mRow3.getKey())).thenReturn(mRow3); - assertEquals(mBubbleData.getBubbles().size(), 3); - - mBubbleData.setMaxOverflowBubbles(1); - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - assertEquals(mBubbleData.getBubbles().size(), 2); - assertEquals(mBubbleData.getOverflowBubbles().size(), 1); - - mBubbleController.removeBubble( - mRow2.getKey(), Bubbles.DISMISS_USER_GESTURE); - // Overflow max of 1 is reached; mRow is oldest, so it gets removed - verify(mNotificationEntryManager, times(1)).performRemoveNotification( - eq(mRow.getSbn()), any(), eq(REASON_CANCEL)); - assertEquals(mBubbleData.getBubbles().size(), 1); - assertEquals(mBubbleData.getOverflowBubbles().size(), 1); - } - - @Test public void testNotifyShadeSuppressionChange_notificationDismiss() { - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); assertTrue(mBubbleController.hasBubbles()); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - mRemoveInterceptor.onNotificationRemoveRequested( - mRow.getKey(), mRow, REASON_CANCEL); + mBubblesManager.handleDismissalInterception(mRow); // Should update show in shade state assertBubbleNotificationSuppressedFromShade(mBubbleEntry); @@ -1022,7 +890,7 @@ public class BubblesTest extends SysuiTestCase { @Test public void testNotifyShadeSuppressionChange_bubbleExpanded() { - mEntryListener.onPendingEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow); assertTrue(mBubbleController.hasBubbles()); assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); @@ -1042,9 +910,9 @@ public class BubblesTest extends SysuiTestCase { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); + mEntryListener.onEntryAdded(groupedBubble.getEntry()); when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) .thenReturn(groupedBubble.getEntry()); - mEntryListener.onPendingEntryAdded(groupedBubble.getEntry()); groupSummary.addChildNotification(groupedBubble); assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); @@ -1054,10 +922,10 @@ public class BubblesTest extends SysuiTestCase { // THEN the summary and bubbled child are suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getEntry().getKey(), - groupSummary.getEntry().getSbn().getGroupKey())); + groupedBubble.getEntry().getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupedBubble.getEntry().getKey(), - groupSummary.getEntry().getSbn().getGroupKey())); + groupedBubble.getEntry().getSbn().getGroupKey())); assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey())); } @@ -1066,7 +934,7 @@ public class BubblesTest extends SysuiTestCase { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); - mEntryListener.onPendingEntryAdded(groupedBubble.getEntry()); + mEntryListener.onEntryAdded(groupedBubble.getEntry()); when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) .thenReturn(groupedBubble.getEntry()); groupSummary.addChildNotification(groupedBubble); @@ -1076,7 +944,7 @@ public class BubblesTest extends SysuiTestCase { mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // WHEN the summary is cancelled by the app - mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL); + mEntryListener.onEntryRemoved(groupSummary.getEntry(), REASON_APP_CANCEL); // THEN the summary and its children are removed from bubble data assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); @@ -1085,14 +953,14 @@ public class BubblesTest extends SysuiTestCase { } @Test - public void testSummaryDismissal_marksBubblesHiddenFromShadeAndDismissesNonBubbledChildren() + public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren() throws Exception { // GIVEN a group summary with two (non-bubble) children and one bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); + mEntryListener.onEntryAdded(groupedBubble.getEntry()); when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) .thenReturn(groupedBubble.getEntry()); - mEntryListener.onPendingEntryAdded(groupedBubble.getEntry()); groupSummary.addChildNotification(groupedBubble); // WHEN the summary is dismissed @@ -1100,16 +968,15 @@ public class BubblesTest extends SysuiTestCase { // THEN only the NON-bubble children are dismissed List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); - verify(mNotificationEntryManager, times(1)).performRemoveNotification( - eq(childrenRows.get(0).getEntry().getSbn()), any(), - eq(REASON_GROUP_SUMMARY_CANCELED)); - verify(mNotificationEntryManager, times(1)).performRemoveNotification( - eq(childrenRows.get(1).getEntry().getSbn()), any(), - eq(REASON_GROUP_SUMMARY_CANCELED)); - verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(groupedBubble.getEntry().getSbn()), any(), anyInt()); - - // THEN the bubble child is suppressed from the shade + verify(mNotifCallback, times(1)).removeNotification( + eq(childrenRows.get(0).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); + verify(mNotifCallback, times(1)).removeNotification( + eq(childrenRows.get(1).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); + verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()), + any(), anyInt()); + + // THEN the bubble child still exists as a bubble and is suppressed from the shade + assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getEntry().getKey(), groupedBubble.getEntry().getSbn().getGroupKey())); @@ -1117,34 +984,17 @@ public class BubblesTest extends SysuiTestCase { groupedBubble.getEntry().getKey(), groupedBubble.getEntry().getSbn().getGroupKey())); - // THEN the summary is removed from GroupManager - verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry()); + // THEN the summary is also suppressed from the shade + assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( + groupSummary.getEntry().getKey(), + groupSummary.getEntry().getSbn().getGroupKey())); + assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( + groupSummary.getEntry().getKey(), + groupSummary.getEntry().getSbn().getGroupKey())); } /** - * Verifies that when a non visually interruptive update occurs for a bubble in the overflow, - * the that bubble does not get promoted from the overflow. - */ - @Test - public void test_notVisuallyInterruptive_updateOverflowBubble_notAdded() { - // Setup - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - assertTrue(mBubbleController.hasBubbles()); - - // Overflow it - mBubbleData.dismissBubbleWithKey(mRow.getKey(), - Bubbles.DISMISS_USER_GESTURE); - assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getKey())).isFalse(); - assertThat(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())).isTrue(); - - // Test - mBubbleController.updateBubble(mBubbleEntry); - assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getKey())).isFalse(); - } - - /** * Verifies that when the user changes, the bubbles in the overflow list is cleared. Doesn't * test the loading from the repository which would be a nice thing to add. */ @@ -1185,15 +1035,17 @@ public class BubblesTest extends SysuiTestCase { */ @Test public void testOverflowLoadedOnce() { - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); + // XXX + when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); + when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2); + + mEntryListener.onEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow2); mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - assertThat(mBubbleData.getOverflowBubbles().isEmpty()).isFalse(); + assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - mBubbleController.removeBubble(mBubbleEntry.getKey(), DISMISS_NOTIF_CANCEL); - mBubbleController.removeBubble(mBubbleEntry2.getKey(), DISMISS_NOTIF_CANCEL); + mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL); + mEntryListener.onEntryRemoved(mRow2, REASON_APP_CANCEL); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); verify(mDataRepository, times(1)).loadBubbles(anyInt(), any()); @@ -1376,6 +1228,7 @@ public class BubblesTest extends SysuiTestCase { assertStackCollapsed(); } + @Test public void testRegisterUnregisterBroadcastListener() { spyOn(mContext); @@ -1455,7 +1308,7 @@ public class BubblesTest extends SysuiTestCase { @Test public void testSetShouldAutoExpand_notifiesFlagChanged() { - mEntryListener.onPendingEntryAdded(mRow); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey()); @@ -1551,7 +1404,7 @@ public class BubblesTest extends SysuiTestCase { } /** - * Sets the bubble metadata flags for this entry. These ]flags are normally set by + * Sets the bubble metadata flags for this entry. These flags are normally set by * NotificationManagerService when the notification is sent, however, these tests do not * go through that path so we set them explicitly when testing. */ @@ -1570,12 +1423,15 @@ public class BubblesTest extends SysuiTestCase { private Notification.BubbleMetadata getMetadata() { Intent target = new Intent(mContext, BubblesTestActivity.class); PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, FLAG_MUTABLE); - - return new Notification.BubbleMetadata.Builder(bubbleIntent, - Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble)) + return new Notification.BubbleMetadata.Builder( + bubbleIntent, + Icon.createWithResource( + mContext, + com.android.wm.shell.R.drawable.bubble_ic_create_bubble)) .build(); } + /** * Asserts that the bubble stack is expanded and also validates the cached state is updated. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java deleted file mode 100644 index a6327b9daed5..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java +++ /dev/null @@ -1,1401 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.wmshell; - -import static android.app.Notification.FLAG_BUBBLE; -import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED; -import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED; -import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.IActivityManager; -import android.app.INotificationManager; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.LauncherApps; -import android.content.pm.UserInfo; -import android.hardware.display.AmbientDisplayConfiguration; -import android.os.Handler; -import android.os.PowerManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.service.dreams.IDreamManager; -import android.service.notification.NotificationListenerService; -import android.service.notification.ZenModeConfig; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; -import android.util.Pair; -import android.util.SparseArray; -import android.view.View; -import android.view.WindowManager; - -import androidx.test.filters.SmallTest; - -import com.android.internal.colorextraction.ColorExtractor; -import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.biometrics.AuthController; -import com.android.systemui.colorextraction.SysuiColorExtractor; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.keyguard.KeyguardViewMediator; -import com.android.systemui.model.SysUiState; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.system.QuickStepContract; -import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.RankingBuilder; -import com.android.systemui.statusbar.SysuiStatusBarStateController; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.NotificationFilter; -import com.android.systemui.statusbar.notification.collection.NotifPipeline; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; -import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; -import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; -import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.notification.row.NotificationTestHelper; -import com.android.systemui.statusbar.phone.DozeParameters; -import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; -import com.android.systemui.statusbar.phone.ScreenOffAnimationController; -import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.HeadsUpManager; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.wm.shell.ShellTaskOrganizer; -import com.android.wm.shell.TaskViewTransitions; -import com.android.wm.shell.WindowManagerShellWrapper; -import com.android.wm.shell.bubbles.Bubble; -import com.android.wm.shell.bubbles.BubbleData; -import com.android.wm.shell.bubbles.BubbleDataRepository; -import com.android.wm.shell.bubbles.BubbleEntry; -import com.android.wm.shell.bubbles.BubbleLogger; -import com.android.wm.shell.bubbles.BubbleStackView; -import com.android.wm.shell.bubbles.Bubbles; -import com.android.wm.shell.common.DisplayController; -import com.android.wm.shell.common.FloatingContentCoordinator; -import com.android.wm.shell.common.ShellExecutor; -import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.common.TaskStackListenerImpl; -import com.android.wm.shell.draganddrop.DragAndDropController; -import com.android.wm.shell.onehanded.OneHandedController; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.HashMap; -import java.util.List; -import java.util.Optional; - -/** - * Tests the NotifPipeline setup with BubbleController. - * The NotificationEntryManager setup with BubbleController is tested in - * {@link BubblesTest}. - */ -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper(setAsMainLooper = true) -public class NewNotifPipelineBubblesTest extends SysuiTestCase { - @Mock - private NotificationEntryManager mNotificationEntryManager; - @Mock - private CommonNotifCollection mCommonNotifCollection; - @Mock - private NotificationGroupManagerLegacy mNotificationGroupManager; - @Mock - private BubblesManager.NotifCallback mNotifCallback; - @Mock - private WindowManager mWindowManager; - @Mock - private IActivityManager mActivityManager; - @Mock - private DozeParameters mDozeParameters; - @Mock - private ConfigurationController mConfigurationController; - @Mock - private ZenModeController mZenModeController; - @Mock - private ZenModeConfig mZenModeConfig; - @Mock - private NotificationLockscreenUserManager mLockscreenUserManager; - @Mock - private SysuiStatusBarStateController mStatusBarStateController; - @Mock - private KeyguardViewMediator mKeyguardViewMediator; - @Mock - private KeyguardBypassController mKeyguardBypassController; - @Mock - private FloatingContentCoordinator mFloatingContentCoordinator; - @Mock - private BubbleDataRepository mDataRepository; - @Mock - private NotificationShadeWindowView mNotificationShadeWindowView; - @Mock - private AuthController mAuthController; - - private SysUiState mSysUiState; - private boolean mSysUiStateBubblesExpanded; - private boolean mSysUiStateBubblesManageMenuExpanded; - - @Captor - private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor; - @Captor - private ArgumentCaptor<List<Bubble>> mBubbleListCaptor; - @Captor - private ArgumentCaptor<IntentFilter> mFilterArgumentCaptor; - @Captor - private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor; - - private BubblesManager mBubblesManager; - private TestableBubbleController mBubbleController; - private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; - private NotifCollectionListener mEntryListener; - private NotificationTestHelper mNotificationTestHelper; - private NotificationEntry mRow; - private NotificationEntry mRow2; - private ExpandableNotificationRow mNonBubbleNotifRow; - private BubbleEntry mBubbleEntry; - private BubbleEntry mBubbleEntry2; - - private BubbleEntry mBubbleEntryUser11; - private BubbleEntry mBubbleEntry2User11; - - @Mock - private Bubbles.BubbleExpandListener mBubbleExpandListener; - @Mock - private PendingIntent mDeleteIntent; - @Mock - private SysuiColorExtractor mColorExtractor; - @Mock - ColorExtractor.GradientColors mGradientColors; - @Mock - private ShadeController mShadeController; - @Mock - private NotifPipeline mNotifPipeline; - @Mock - private NotifPipelineFlags mNotifPipelineFlags; - @Mock - private DumpManager mDumpManager; - @Mock - private IStatusBarService mStatusBarService; - @Mock - private NotificationVisibilityProvider mVisibilityProvider; - @Mock - private LauncherApps mLauncherApps; - @Mock - private WindowManagerShellWrapper mWindowManagerShellWrapper; - @Mock - private BubbleLogger mBubbleLogger; - @Mock - private TaskStackListenerImpl mTaskStackListener; - @Mock - private ShellTaskOrganizer mShellTaskOrganizer; - @Mock - private KeyguardStateController mKeyguardStateController; - @Mock - private ScreenOffAnimationController mScreenOffAnimationController; - @Mock - private TaskViewTransitions mTaskViewTransitions; - @Mock - private Optional<OneHandedController> mOneHandedOptional; - - private TestableBubblePositioner mPositioner; - - private BubbleData mBubbleData; - - private TestableLooper mTestableLooper; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mTestableLooper = TestableLooper.get(this); - - // For the purposes of this test, just run everything synchronously - ShellExecutor syncExecutor = new SyncExecutor(); - - when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); - - mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, - mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, - mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, - mColorExtractor, mDumpManager, mKeyguardStateController, - mScreenOffAnimationController, mAuthController); - mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); - mNotificationShadeWindowController.attach(); - - // Need notifications for bubbles - mNotificationTestHelper = new NotificationTestHelper( - mContext, - mDependency, - TestableLooper.get(this)); - mRow = mNotificationTestHelper.createBubble(mDeleteIntent); - mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent); - mNonBubbleNotifRow = mNotificationTestHelper.createRow(); - mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow); - mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2); - - UserHandle handle = mock(UserHandle.class); - when(handle.getIdentifier()).thenReturn(11); - mBubbleEntryUser11 = BubblesManager.notifToBubbleEntry( - mNotificationTestHelper.createBubble(handle)); - mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry( - mNotificationTestHelper.createBubble(handle)); - - mZenModeConfig.suppressedVisualEffects = 0; - when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); - - mSysUiState = new SysUiState(); - mSysUiState.addCallback(sysUiFlags -> { - mSysUiStateBubblesManageMenuExpanded = - (sysUiFlags - & QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0; - mSysUiStateBubblesExpanded = - (sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0; - }); - - mPositioner = new TestableBubblePositioner(mContext, mWindowManager); - mPositioner.setMaxBubbles(5); - mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor); - - TestableNotificationInterruptStateProviderImpl interruptionStateProvider = - new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(), - mock(PowerManager.class), - mock(IDreamManager.class), - mock(AmbientDisplayConfiguration.class), - mock(NotificationFilter.class), - mock(StatusBarStateController.class), - mock(BatteryController.class), - mock(HeadsUpManager.class), - mock(NotificationInterruptLogger.class), - mock(Handler.class), - mock(NotifPipelineFlags.class), - mock(KeyguardNotificationVisibilityProvider.class) - ); - when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(true); - when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor); - mBubbleController = new TestableBubbleController( - mContext, - mBubbleData, - mFloatingContentCoordinator, - mDataRepository, - mStatusBarService, - mWindowManager, - mWindowManagerShellWrapper, - mock(UserManager.class), - mLauncherApps, - mBubbleLogger, - mTaskStackListener, - mShellTaskOrganizer, - mPositioner, - mock(DisplayController.class), - mOneHandedOptional, - mock(DragAndDropController.class), - syncExecutor, - mock(Handler.class), - mTaskViewTransitions, - mock(SyncTransactionQueue.class)); - mBubbleController.setExpandListener(mBubbleExpandListener); - spyOn(mBubbleController); - - mBubblesManager = new BubblesManager( - mContext, - mBubbleController.asBubbles(), - mNotificationShadeWindowController, - mock(KeyguardStateController.class), - mShadeController, - mConfigurationController, - mStatusBarService, - mock(INotificationManager.class), - mVisibilityProvider, - interruptionStateProvider, - mZenModeController, - mLockscreenUserManager, - mNotificationGroupManager, - mNotificationEntryManager, - mCommonNotifCollection, - mNotifPipeline, - mSysUiState, - mNotifPipelineFlags, - mDumpManager, - syncExecutor); - mBubblesManager.addNotifCallback(mNotifCallback); - - // Get a reference to the BubbleController's entry listener - verify(mNotifPipeline, atLeastOnce()) - .addCollectionListener(mNotifListenerCaptor.capture()); - mEntryListener = mNotifListenerCaptor.getValue(); - } - - @Test - public void testAddBubble() { - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testHasBubbles() { - assertFalse(mBubbleController.hasBubbles()); - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testRemoveBubble() { - mBubbleController.updateBubble(mBubbleEntry); - assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - assertTrue(mBubbleController.hasBubbles()); - verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); - - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); - - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testRemoveBubble_withDismissedNotif_inOverflow() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Make it look like dismissed notif - mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true); - - // Now remove the bubble - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())); - - // We don't remove the notification since the bubble is still in overflow. - verify(mNotifCallback, never()).removeNotification(eq(mRow), any(), anyInt()); - assertFalse(mBubbleController.hasBubbles()); - } - - @Test - public void testRemoveBubble_withDismissedNotif_notInOverflow() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Make it look like dismissed notif - mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true); - - // Now remove the bubble - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); - assertFalse(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())); - - // Since the notif is dismissed and not in overflow, once the bubble is removed, - // removeNotification gets called to really remove the notif - verify(mNotifCallback, times(1)).removeNotification(eq(mRow), - any(), anyInt()); - assertFalse(mBubbleController.hasBubbles()); - } - - @Test - public void testDismissStack() { - mBubbleController.updateBubble(mBubbleEntry); - verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); - assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - mBubbleController.updateBubble(mBubbleEntry2); - verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); - assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey())); - assertTrue(mBubbleController.hasBubbles()); - - mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - verify(mNotifCallback, times(3)).invalidateNotifications(anyString()); - assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey())); - - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testExpandCollapseStack() { - assertStackCollapsed(); - - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // We should have bubbles & their notifs should not be suppressed - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Expand the stack - mBubbleData.setExpanded(true); - assertStackExpanded(); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Make sure the notif is suppressed - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - - // Collapse - mBubbleController.collapseStack(); - verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey()); - assertStackCollapsed(); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - @Ignore("Currently broken.") - public void testCollapseAfterChangingExpandedBubble() { - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mEntryListener.onEntryAdded(mRow2); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - - // We should have bubbles & their notifs should not be suppressed - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry2); - - // Expand - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - assertStackExpanded(); - verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( - true, mRow2.getKey()); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Last added is the one that is expanded - assertEquals(mRow2.getKey(), mBubbleData.getSelectedBubble().getKey()); - assertBubbleNotificationSuppressedFromShade(mBubbleEntry2); - - // Switch which bubble is expanded - mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey( - mRow.getKey())); - mBubbleData.setExpanded(true); - assertEquals(mRow.getKey(), mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey()); - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - - // collapse for previous bubble - verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( - false, mRow2.getKey()); - // expand for selected bubble - verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( - true, mRow.getKey()); - - - // Collapse - mBubbleController.collapseStack(); - assertStackCollapsed(); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testExpansionRemovesShowInShadeAndDot() { - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // We should have bubbles & their notifs should not be suppressed - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - mTestableLooper.processAllMessages(); - assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - - // Expand - mBubbleData.setExpanded(true); - assertStackExpanded(); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Notif is suppressed after expansion - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - // Notif shouldn't show dot after expansion - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - } - - @Test - public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() { - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // We should have bubbles & their notifs should not be suppressed - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - mTestableLooper.processAllMessages(); - assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - - // Expand - mBubbleData.setExpanded(true); - assertStackExpanded(); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Notif is suppressed after expansion - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - // Notif shouldn't show dot after expansion - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - - // Send update - mEntryListener.onEntryUpdated(mRow); - - // Nothing should have changed - // Notif is suppressed after expansion - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - // Notif shouldn't show dot after expansion - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - } - - @Test - public void testRemoveLastExpanded_collapses() { - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mEntryListener.onEntryAdded(mRow2); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - - // Expand - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - assertStackExpanded(); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getKey()); - - // Last added is the one that is expanded - assertEquals(mRow2.getKey(), mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey()); - assertBubbleNotificationSuppressedFromShade(mBubbleEntry2); - - // Dismiss currently expanded - mBubbleController.removeBubble( - mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey(), - Bubbles.DISMISS_USER_GESTURE); - verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getKey()); - - // Make sure first bubble is selected - assertEquals(mRow.getKey(), mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey()); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); - - // Dismiss that one - mBubbleController.removeBubble( - mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey(), - Bubbles.DISMISS_USER_GESTURE); - - // We should be collapsed - verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey()); - assertFalse(mBubbleController.hasBubbles()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testRemoveLastExpandedEmptyOverflow_collapses() { - // Mark it as a bubble and add it explicitly - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // Expand - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - assertStackExpanded(); - verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey()); - - // Block the bubble so it won't be in the overflow - mBubbleController.removeBubble( - mBubbleData.getBubbleInStackWithKey( - stackView.getExpandedBubble().getKey()).getKey(), - Bubbles.DISMISS_BLOCKED); - - verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey()); - - // We should be collapsed - verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey()); - assertFalse(mBubbleController.hasBubbles()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - - @Test - public void testAutoExpand_fails_noFlag() { - assertStackCollapsed(); - setMetadataFlags(mRow, - Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */); - - // Add the auto expand bubble - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // Expansion shouldn't change - verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */, - mRow.getKey()); - assertStackCollapsed(); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testAutoExpand_succeeds_withFlag() { - setMetadataFlags(mRow, - Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */); - - // Add the auto expand bubble - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // Expansion should change - verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */, - mRow.getKey()); - assertStackExpanded(); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testSuppressNotif_onInitialNotif() { - setMetadataFlags(mRow, - Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */); - - // Add the suppress notif bubble - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - // Notif should be suppressed because we were foreground - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - // Dot + flyout is hidden because notif is suppressed - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showFlyout()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testSuppressNotif_onUpdateNotif() { - mBubbleController.updateBubble(mBubbleEntry); - - // Should not be suppressed - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - // Should show dot - assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - - // Update to suppress notif - setMetadataFlags(mRow, - Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */); - mBubbleController.updateBubble(mBubbleEntry); - - // Notif should be suppressed - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - // Dot + flyout is hidden because notif is suppressed - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showFlyout()); - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testMarkNewNotificationAsShowInShade() { - mEntryListener.onEntryAdded(mRow); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - mTestableLooper.processAllMessages(); - assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot()); - } - - @Test - public void testAddNotif_notBubble() { - mEntryListener.onEntryAdded(mNonBubbleNotifRow.getEntry()); - mEntryListener.onEntryUpdated(mNonBubbleNotifRow.getEntry()); - - assertThat(mBubbleController.hasBubbles()).isFalse(); - } - - @Test - public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_AGED); - verify(mDeleteIntent, never()).send(); - } - - @Test - public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.removeBubble( - mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - verify(mDeleteIntent, times(1)).send(); - } - - @Test - public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - verify(mDeleteIntent, times(2)).send(); - } - - @Test - public void testRemoveBubble_noLongerBubbleAfterUpdate() - throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - - mRow.getSbn().getNotification().flags &= ~FLAG_BUBBLE; - NotificationListenerService.Ranking ranking = new RankingBuilder( - mRow.getRanking()).setCanBubble(false).build(); - mRow.setRanking(ranking); - mEntryListener.onEntryUpdated(mRow); - - assertFalse(mBubbleController.hasBubbles()); - verify(mDeleteIntent, never()).send(); - } - - @Test - public void testRemoveBubble_entryListenerRemove() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - - // Removes the notification - mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL); - assertFalse(mBubbleController.hasBubbles()); - } - - @Test - public void removeBubble_intercepted() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); - - // Intercept! - assertTrue(intercepted); - // Should update show in shade state - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - } - - @Test - public void removeBubble_dismissIntoOverflow_intercepted() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Dismiss the bubble - mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); - assertFalse(mBubbleController.hasBubbles()); - - // Dismiss the notification - boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); - - // Intercept dismissal since bubble is going into overflow - assertTrue(intercepted); - } - - @Test - public void removeBubble_notIntercepted() { - mEntryListener.onEntryAdded(mRow); - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - // Dismiss the bubble - mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); - assertFalse(mBubbleController.hasBubbles()); - - // Dismiss the notification - boolean intercepted = mBubblesManager.handleDismissalInterception(mRow); - - // Not a bubble anymore so we don't intercept dismissal. - assertFalse(intercepted); - } - - @Test - public void testNotifyShadeSuppressionChange_notificationDismiss() { - mEntryListener.onEntryAdded(mRow); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - mBubblesManager.handleDismissalInterception(mRow); - - // Should update show in shade state - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - - // Should notify delegate that shade state changed - verify(mBubbleController).onBubbleMetadataFlagChanged( - mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - } - - @Test - public void testNotifyShadeSuppressionChange_bubbleExpanded() { - mEntryListener.onEntryAdded(mRow); - - assertTrue(mBubbleController.hasBubbles()); - assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry); - - mBubbleData.setExpanded(true); - - // Once a bubble is expanded the notif is suppressed - assertBubbleNotificationSuppressedFromShade(mBubbleEntry); - - // Should notify delegate that shade state changed - verify(mBubbleController).onBubbleMetadataFlagChanged( - mBubbleData.getBubbleInStackWithKey(mRow.getKey())); - } - - @Test - public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade() throws Exception { - // GIVEN a group summary with a bubble child - ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); - ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); - mEntryListener.onEntryAdded(groupedBubble.getEntry()); - when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) - .thenReturn(groupedBubble.getEntry()); - groupSummary.addChildNotification(groupedBubble); - assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); - - // WHEN the summary is dismissed - mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); - - // THEN the summary and bubbled child are suppressed from the shade - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry().getKey(), - groupedBubble.getEntry().getSbn().getGroupKey())); - assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry().getKey(), - groupedBubble.getEntry().getSbn().getGroupKey())); - assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey())); - } - - @Test - public void testAppRemovesSummary_removesAllBubbleChildren() throws Exception { - // GIVEN a group summary with a bubble child - ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); - ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); - mEntryListener.onEntryAdded(groupedBubble.getEntry()); - when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) - .thenReturn(groupedBubble.getEntry()); - groupSummary.addChildNotification(groupedBubble); - assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); - - // GIVEN the summary is dismissed - mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); - - // WHEN the summary is cancelled by the app - mEntryListener.onEntryRemoved(groupSummary.getEntry(), REASON_APP_CANCEL); - - // THEN the summary and its children are removed from bubble data - assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); - assertFalse(mBubbleData.isSummarySuppressed( - groupSummary.getEntry().getSbn().getGroupKey())); - } - - @Test - public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren() - throws Exception { - // GIVEN a group summary with two (non-bubble) children and one bubble child - ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2); - ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); - mEntryListener.onEntryAdded(groupedBubble.getEntry()); - when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey())) - .thenReturn(groupedBubble.getEntry()); - groupSummary.addChildNotification(groupedBubble); - - // WHEN the summary is dismissed - mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); - - // THEN only the NON-bubble children are dismissed - List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); - verify(mNotifCallback, times(1)).removeNotification( - eq(childrenRows.get(0).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); - verify(mNotifCallback, times(1)).removeNotification( - eq(childrenRows.get(1).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); - verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()), - any(), anyInt()); - - // THEN the bubble child still exists as a bubble and is suppressed from the shade - assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry().getKey(), - groupedBubble.getEntry().getSbn().getGroupKey())); - assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry().getKey(), - groupedBubble.getEntry().getSbn().getGroupKey())); - - // THEN the summary is also suppressed from the shade - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupSummary.getEntry().getKey(), - groupSummary.getEntry().getSbn().getGroupKey())); - assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( - groupSummary.getEntry().getKey(), - groupSummary.getEntry().getSbn().getGroupKey())); - } - - - /** - * Verifies that when the user changes, the bubbles in the overflow list is cleared. Doesn't - * test the loading from the repository which would be a nice thing to add. - */ - @Test - public void testOnUserChanged_overflowState() { - int firstUserId = mBubbleEntry.getStatusBarNotification().getUser().getIdentifier(); - int secondUserId = mBubbleEntryUser11.getStatusBarNotification().getUser().getIdentifier(); - - mBubbleController.updateBubble(mBubbleEntry); - mBubbleController.updateBubble(mBubbleEntry2); - assertTrue(mBubbleController.hasBubbles()); - mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - - // Verify these are in the overflow - assertThat(mBubbleData.getOverflowBubbleWithKey(mBubbleEntry.getKey())).isNotNull(); - assertThat(mBubbleData.getOverflowBubbleWithKey(mBubbleEntry2.getKey())).isNotNull(); - - // Switch users - mBubbleController.onUserChanged(secondUserId); - assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); - - // Give this user some bubbles - mBubbleController.updateBubble(mBubbleEntryUser11); - mBubbleController.updateBubble(mBubbleEntry2User11); - assertTrue(mBubbleController.hasBubbles()); - mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - - // Verify these are in the overflow - assertThat(mBubbleData.getOverflowBubbleWithKey(mBubbleEntryUser11.getKey())).isNotNull(); - assertThat(mBubbleData.getOverflowBubbleWithKey(mBubbleEntry2User11.getKey())).isNotNull(); - - // Would have loaded bubbles twice because of user switch - verify(mDataRepository, times(2)).loadBubbles(anyInt(), any()); - } - - /** - * Verifies we only load the overflow data once. - */ - @Test - public void testOverflowLoadedOnce() { - // XXX - when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow); - when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2); - - mEntryListener.onEntryAdded(mRow); - mEntryListener.onEntryAdded(mRow2); - mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); - assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); - - mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL); - mEntryListener.onEntryRemoved(mRow2, REASON_APP_CANCEL); - assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); - - verify(mDataRepository, times(1)).loadBubbles(anyInt(), any()); - } - - /** - * Verifies that shortcut deletions triggers that bubble being removed from XML. - */ - @Test - public void testDeleteShortcutsDeletesXml() throws Exception { - ExpandableNotificationRow row = mNotificationTestHelper.createShortcutBubble("shortcutId"); - BubbleEntry shortcutBubbleEntry = BubblesManager.notifToBubbleEntry(row.getEntry()); - mBubbleController.updateBubble(shortcutBubbleEntry); - - mBubbleData.dismissBubbleWithKey(shortcutBubbleEntry.getKey(), - Bubbles.DISMISS_SHORTCUT_REMOVED); - - verify(mDataRepository, atLeastOnce()).removeBubbles(anyInt(), mBubbleListCaptor.capture()); - assertThat(mBubbleListCaptor.getValue().get(0).getKey()).isEqualTo( - shortcutBubbleEntry.getKey()); - } - - @Test - public void testShowManageMenuChangesSysuiState() { - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - - // Expand the stack - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - assertStackExpanded(); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Show the menu - stackView.showManageMenu(true); - assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */); - } - - @Test - public void testHideManageMenuChangesSysuiState() { - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - - // Expand the stack - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - assertStackExpanded(); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Show the menu - stackView.showManageMenu(true); - assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */); - - // Hide the menu - stackView.showManageMenu(false); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testCollapseBubbleManageMenuChangesSysuiState() { - mBubbleController.updateBubble(mBubbleEntry); - assertTrue(mBubbleController.hasBubbles()); - - // Expand the stack - BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleData.setExpanded(true); - assertStackExpanded(); - assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */); - - // Show the menu - stackView.showManageMenu(true); - assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */); - - // Collapse the stack - mBubbleData.setExpanded(false); - - assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */); - } - - @Test - public void testNotificationChannelModified_channelUpdated_removesOverflowBubble() - throws Exception { - // Setup - ExpandableNotificationRow row = mNotificationTestHelper.createShortcutBubble("shortcutId"); - NotificationEntry entry = row.getEntry(); - entry.getChannel().setConversationId( - row.getEntry().getChannel().getParentChannelId(), - "shortcutId"); - mBubbleController.updateBubble(BubblesManager.notifToBubbleEntry(row.getEntry())); - assertTrue(mBubbleController.hasBubbles()); - - // Overflow it - mBubbleData.dismissBubbleWithKey(entry.getKey(), - Bubbles.DISMISS_USER_GESTURE); - assertThat(mBubbleData.hasOverflowBubbleWithKey(entry.getKey())).isTrue(); - - // Test - entry.getChannel().setDeleted(true); - mBubbleController.onNotificationChannelModified(entry.getSbn().getPackageName(), - entry.getSbn().getUser(), - entry.getChannel(), - NOTIFICATION_CHANNEL_OR_GROUP_UPDATED); - assertThat(mBubbleData.hasOverflowBubbleWithKey(entry.getKey())).isFalse(); - } - - @Test - public void testNotificationChannelModified_channelDeleted_removesOverflowBubble() - throws Exception { - // Setup - ExpandableNotificationRow row = mNotificationTestHelper.createShortcutBubble("shortcutId"); - NotificationEntry entry = row.getEntry(); - entry.getChannel().setConversationId( - row.getEntry().getChannel().getParentChannelId(), - "shortcutId"); - mBubbleController.updateBubble(BubblesManager.notifToBubbleEntry(row.getEntry())); - assertTrue(mBubbleController.hasBubbles()); - - // Overflow it - mBubbleData.dismissBubbleWithKey(entry.getKey(), - Bubbles.DISMISS_USER_GESTURE); - assertThat(mBubbleData.hasOverflowBubbleWithKey(entry.getKey())).isTrue(); - - // Test - entry.getChannel().setDeleted(true); - mBubbleController.onNotificationChannelModified(entry.getSbn().getPackageName(), - entry.getSbn().getUser(), - entry.getChannel(), - NOTIFICATION_CHANNEL_OR_GROUP_DELETED); - assertThat(mBubbleData.hasOverflowBubbleWithKey(entry.getKey())).isFalse(); - } - - @Test - public void testStackViewOnBackPressed_updatesBubbleDataExpandState() { - mBubbleController.updateBubble(mBubbleEntry); - - // Expand the stack - mBubbleData.setExpanded(true); - assertStackExpanded(); - - // Hit back - BubbleStackView stackView = mBubbleController.getStackView(); - stackView.onBackPressed(); - - // Make sure we're collapsed - assertStackCollapsed(); - } - - - @Test - public void testRegisterUnregisterBroadcastListener() { - spyOn(mContext); - mBubbleController.updateBubble(mBubbleEntry); - verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), - mFilterArgumentCaptor.capture()); - assertThat(mFilterArgumentCaptor.getValue().getAction(0)).isEqualTo( - Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - assertThat(mFilterArgumentCaptor.getValue().getAction(1)).isEqualTo( - Intent.ACTION_SCREEN_OFF); - - mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL); - // TODO: not certain why this isn't called normally when tests are run, perhaps because - // it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe - mBubbleController.onAllBubblesAnimatedOut(); - - verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue())); - } - - @Test - public void testBroadcastReceiverCloseDialogs_notGestureNav() { - spyOn(mContext); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleData.setExpanded(true); - verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), - mFilterArgumentCaptor.capture()); - Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i); - - assertStackExpanded(); - } - - @Test - public void testBroadcastReceiverCloseDialogs_reasonGestureNav() { - spyOn(mContext); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleData.setExpanded(true); - - verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), - mFilterArgumentCaptor.capture()); - Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - i.putExtra("reason", "gestureNav"); - mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i); - assertStackCollapsed(); - } - - @Test - public void testBroadcastReceiver_screenOff() { - spyOn(mContext); - mBubbleController.updateBubble(mBubbleEntry); - mBubbleData.setExpanded(true); - - verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), - mFilterArgumentCaptor.capture()); - - Intent i = new Intent(Intent.ACTION_SCREEN_OFF); - mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i); - assertStackCollapsed(); - } - - @Test - public void testOnStatusBarStateChanged() { - mBubbleController.updateBubble(mBubbleEntry); - mBubbleData.setExpanded(true); - assertStackExpanded(); - BubbleStackView stackView = mBubbleController.getStackView(); - assertThat(stackView.getVisibility()).isEqualTo(View.VISIBLE); - - mBubbleController.onStatusBarStateChanged(false); - - assertStackCollapsed(); - assertThat(stackView.getVisibility()).isEqualTo(View.INVISIBLE); - - mBubbleController.onStatusBarStateChanged(true); - assertThat(stackView.getVisibility()).isEqualTo(View.VISIBLE); - } - - @Test - public void testSetShouldAutoExpand_notifiesFlagChanged() { - mBubbleController.updateBubble(mBubbleEntry); - - assertTrue(mBubbleController.hasBubbles()); - Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey()); - assertThat(b.shouldAutoExpand()).isFalse(); - - // Set it to the same thing - b.setShouldAutoExpand(false); - - // Verify it doesn't notify - verify(mBubbleController, never()).onBubbleMetadataFlagChanged(any()); - - // Set it to something different - b.setShouldAutoExpand(true); - verify(mBubbleController).onBubbleMetadataFlagChanged(b); - } - - @Test - public void testUpdateBubble_skipsDndSuppressListNotifs() { - mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(), - mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */, - mRow.shouldSuppressPeek()); - mBubbleEntry.getBubbleMetadata().setFlags( - Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); - - mBubbleController.updateBubble(mBubbleEntry); - - Bubble b = mBubbleData.getPendingBubbleWithKey(mBubbleEntry.getKey()); - assertThat(b.shouldAutoExpand()).isFalse(); - assertThat(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey())).isNull(); - } - - @Test - public void testOnRankingUpdate_DndSuppressListNotif() { - // It's in the stack - mBubbleController.updateBubble(mBubbleEntry); - assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isTrue(); - - // Set current user profile - SparseArray<UserInfo> userInfos = new SparseArray<>(); - userInfos.put(mBubbleEntry.getStatusBarNotification().getUser().getIdentifier(), - mock(UserInfo.class)); - mBubbleController.onCurrentProfilesChanged(userInfos); - - // Send ranking update that the notif is suppressed from the list. - HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey = new HashMap<>(); - mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(), - mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */, - mRow.shouldSuppressPeek()); - Pair<BubbleEntry, Boolean> pair = new Pair(mBubbleEntry, true); - entryDataByKey.put(mBubbleEntry.getKey(), pair); - - NotificationListenerService.RankingMap rankingMap = - mock(NotificationListenerService.RankingMap.class); - when(rankingMap.getOrderedKeys()).thenReturn(new String[] { mBubbleEntry.getKey() }); - mBubbleController.onRankingUpdated(rankingMap, entryDataByKey); - - // Should no longer be in the stack - assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isFalse(); - } - - /** - * Sets the bubble metadata flags for this entry. These flags are normally set by - * NotificationManagerService when the notification is sent, however, these tests do not - * go through that path so we set them explicitly when testing. - */ - private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) { - Notification.BubbleMetadata bubbleMetadata = - entry.getSbn().getNotification().getBubbleMetadata(); - int flags = bubbleMetadata.getFlags(); - if (enableFlag) { - flags |= flag; - } else { - flags &= ~flag; - } - bubbleMetadata.setFlags(flags); - } - - /** - * Asserts that the bubble stack is expanded and also validates the cached state is updated. - */ - private void assertStackExpanded() { - assertTrue(mBubbleController.isStackExpanded()); - assertTrue(mBubbleController.getImplCachedState().isStackExpanded()); - } - - /** - * Asserts that the bubble stack is collapsed and also validates the cached state is updated. - */ - private void assertStackCollapsed() { - assertFalse(mBubbleController.isStackExpanded()); - assertFalse(mBubbleController.getImplCachedState().isStackExpanded()); - } - - /** - * Asserts that a bubble notification is suppressed from the shade and also validates the cached - * state is updated. - */ - private void assertBubbleNotificationSuppressedFromShade(BubbleEntry entry) { - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - entry.getKey(), entry.getGroupKey())); - assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( - entry.getKey(), entry.getGroupKey())); - } - - /** - * Asserts that a bubble notification is not suppressed from the shade and also validates the - * cached state is updated. - */ - private void assertBubbleNotificationNotSuppressedFromShade(BubbleEntry entry) { - assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - entry.getKey(), entry.getGroupKey())); - assertFalse(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( - entry.getKey(), entry.getGroupKey())); - } - - /** - * Asserts that the system ui states associated to bubbles are in the correct state. - */ - private void assertSysuiStates(boolean stackExpanded, boolean manageMenuExpanded) { - assertThat(mSysUiStateBubblesExpanded).isEqualTo(stackExpanded); - assertThat(mSysUiStateBubblesManageMenuExpanded).isEqualTo(manageMenuExpanded); - } -} diff --git a/packages/VpnDialogs/res/values-te/strings.xml b/packages/VpnDialogs/res/values-te/strings.xml index 8f8ff0778d06..78843360bdab 100644 --- a/packages/VpnDialogs/res/values-te/strings.xml +++ b/packages/VpnDialogs/res/values-te/strings.xml @@ -17,7 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="prompt" msgid="3183836924226407828">"కనెక్షన్ రిక్వెస్ట్"</string> - <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్వర్క్ ట్రాఫిక్ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN సక్రియంగా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన <br /> <br /> <img src=vpn_icon /> కనిపిస్తుంది."</string> + <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్వర్క్ ట్రాఫిక్ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN యాక్టివ్గా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన <br /> <br /> <img src=vpn_icon /> కనిపిస్తుంది."</string> <string name="warning" product="tv" msgid="5188957997628124947">"నెట్వర్క్ ట్రాఫిక్ను పర్యవేక్షించగలగడానికి, <xliff:g id="APP">%s</xliff:g> VPN కనెక్షన్ను సెటప్ చేయాలనుకుంటోంది. మీరు సోర్స్ను విశ్వసిస్తే మాత్రమే ఆమోదించండి. <br /> <br /> <img src=vpn_icon /> VPN యాక్టివ్గా ఉన్నప్పుడు మీ స్క్రీన్ పై కనిపిస్తుంది."</string> <string name="legacy_title" msgid="192936250066580964">"VPN కనెక్ట్ చేయబడింది"</string> <string name="session" msgid="6470628549473641030">"సెషన్:"</string> diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java index 966d887d11f7..dc39b01cf6b6 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -184,7 +184,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mPanningScalingState.mScrollGestureDetector.onTouchEvent(event); mPanningScalingState.mScaleGestureDetector.onTouchEvent(event); - stateHandler.onMotionEvent(event, rawEvent, policyFlags); + try { + stateHandler.onMotionEvent(event, rawEvent, policyFlags); + } catch (GestureException e) { + Slog.e(mLogTag, "Error processing motion event", e); + clearAndTransitionToStateDetecting(); + } } @Override @@ -281,7 +286,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } interface State { - void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags); + void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) + throws GestureException; default void clear() {} @@ -439,7 +445,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH private boolean mLastMoveOutsideMagnifiedRegion; @Override - public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) + throws GestureException { final int action = event.getActionMasked(); switch (action) { case ACTION_POINTER_DOWN: { @@ -449,7 +456,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH break; case ACTION_MOVE: { if (event.getPointerCount() != 1) { - throw new IllegalStateException("Should have one pointer down."); + throw new GestureException("Should have one pointer down."); } final float eventX = event.getX(); final float eventY = event.getY(); @@ -475,7 +482,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH case ACTION_DOWN: case ACTION_POINTER_UP: { - throw new IllegalArgumentException( + throw new GestureException( "Unexpected event type: " + MotionEvent.actionToString(action)); } } @@ -1087,4 +1094,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mGestureHandler.mDetectingState.setShortcutTriggered(false); } } + + /** + * Indicates an error with a gesture handler or state. + */ + private static class GestureException extends Exception { + GestureException(String message) { + super(message); + } + } } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 2aabac4201be..abc49372053e 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -104,6 +104,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.companion.presence.CompanionDevicePresenceMonitor; import com.android.server.pm.UserManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import java.io.File; import java.io.FileDescriptor; @@ -143,6 +144,7 @@ public class CompanionDeviceManagerService extends SystemService { private CompanionDevicePresenceMonitor mDevicePresenceMonitor; private CompanionApplicationController mCompanionAppController; + private final ActivityTaskManagerInternal mAtmInternal; private final ActivityManagerInternal mAmInternal; private final IAppOpsService mAppOpsManager; private final PowerWhitelistManager mPowerWhitelistManager; @@ -195,6 +197,7 @@ public class CompanionDeviceManagerService extends SystemService { mPowerWhitelistManager = context.getSystemService(PowerWhitelistManager.class); mAppOpsManager = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); + mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mUserManager = context.getSystemService(UserManager.class); @@ -1199,6 +1202,9 @@ public class CompanionDeviceManagerService extends SystemService { companionAppUids.add(uid); } } + if (mAtmInternal != null) { + mAtmInternal.setCompanionAppUids(userId, companionAppUids); + } if (mAmInternal != null) { // Make a copy of the set and send it to ActivityManager. mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids)); diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 297d28dadde3..56990eda3e78 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -19,7 +19,7 @@ package com.android.server.adb; import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import android.annotation.NonNull; -import android.annotation.TestApi; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.Notification; import android.app.NotificationChannel; @@ -102,11 +102,26 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** - * Provides communication to the Android Debug Bridge daemon to allow, deny, or clear public keysi + * Provides communication to the Android Debug Bridge daemon to allow, deny, or clear public keys * that are authorized to connect to the ADB service itself. + * + * <p>The AdbDebuggingManager controls two files: + * <ol> + * <li>adb_keys + * <li>adb_temp_keys.xml + * </ol> + * + * <p>The ADB Daemon (adbd) reads <em>only</em> the adb_keys file for authorization. Public keys + * from registered hosts are stored in adb_keys, one entry per line. + * + * <p>AdbDebuggingManager also keeps adb_temp_keys.xml, which is used for two things + * <ol> + * <li>Removing unused keys from the adb_keys file + * <li>Managing authorized WiFi access points for ADB over WiFi + * </ol> */ public class AdbDebuggingManager { - private static final String TAG = "AdbDebuggingManager"; + private static final String TAG = AdbDebuggingManager.class.getSimpleName(); private static final boolean DEBUG = false; private static final boolean MDNS_DEBUG = false; @@ -118,18 +133,20 @@ public class AdbDebuggingManager { // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final int BUFFER_SIZE = 65536; + private static final Ticker SYSTEM_TICKER = () -> System.currentTimeMillis(); private final Context mContext; private final ContentResolver mContentResolver; - private final Handler mHandler; - private AdbDebuggingThread mThread; + @VisibleForTesting final AdbDebuggingHandler mHandler; + @Nullable private AdbDebuggingThread mThread; private boolean mAdbUsbEnabled = false; private boolean mAdbWifiEnabled = false; private String mFingerprints; // A key can be used more than once (e.g. USB, wifi), so need to keep a refcount - private final Map<String, Integer> mConnectedKeys; - private String mConfirmComponent; - private final File mTestUserKeyFile; + private final Map<String, Integer> mConnectedKeys = new HashMap<>(); + private final String mConfirmComponent; + @Nullable private final File mUserKeyFile; + @Nullable private final File mTempKeysFile; private static final String WIFI_PERSISTENT_CONFIG_PROPERTY = "persist.adb.tls_server.enable"; @@ -138,37 +155,44 @@ public class AdbDebuggingManager { private static final int PAIRING_CODE_LENGTH = 6; private PairingThread mPairingThread = null; // A list of keys connected via wifi - private final Set<String> mWifiConnectedKeys; + private final Set<String> mWifiConnectedKeys = new HashSet<>(); // The current info of the adbwifi connection. - private AdbConnectionInfo mAdbConnectionInfo; + private AdbConnectionInfo mAdbConnectionInfo = new AdbConnectionInfo(); // Polls for a tls port property when adb wifi is enabled private AdbConnectionPortPoller mConnectionPortPoller; private final PortListenerImpl mPortListener = new PortListenerImpl(); + private final Ticker mTicker; public AdbDebuggingManager(Context context) { - mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); - mContext = context; - mContentResolver = mContext.getContentResolver(); - mTestUserKeyFile = null; - mConnectedKeys = new HashMap<String, Integer>(); - mWifiConnectedKeys = new HashSet<String>(); - mAdbConnectionInfo = new AdbConnectionInfo(); + this( + context, + /* confirmComponent= */ null, + getAdbFile(ADB_KEYS_FILE), + getAdbFile(ADB_TEMP_KEYS_FILE), + /* adbDebuggingThread= */ null, + SYSTEM_TICKER); } /** * Constructor that accepts the component to be invoked to confirm if the user wants to allow * an adb connection from the key. */ - @TestApi - protected AdbDebuggingManager(Context context, String confirmComponent, File testUserKeyFile) { - mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); + @VisibleForTesting + AdbDebuggingManager( + Context context, + String confirmComponent, + File testUserKeyFile, + File tempKeysFile, + AdbDebuggingThread adbDebuggingThread, + Ticker ticker) { mContext = context; mContentResolver = mContext.getContentResolver(); mConfirmComponent = confirmComponent; - mTestUserKeyFile = testUserKeyFile; - mConnectedKeys = new HashMap<String, Integer>(); - mWifiConnectedKeys = new HashSet<String>(); - mAdbConnectionInfo = new AdbConnectionInfo(); + mUserKeyFile = testUserKeyFile; + mTempKeysFile = tempKeysFile; + mThread = adbDebuggingThread; + mTicker = ticker; + mHandler = new AdbDebuggingHandler(FgThread.get().getLooper(), mThread); } static void sendBroadcastWithDebugPermission(@NonNull Context context, @NonNull Intent intent, @@ -189,8 +213,7 @@ public class AdbDebuggingManager { // consisting of only letters, digits, and hyphens, must begin and end // with a letter or digit, must not contain consecutive hyphens, and // must contain at least one letter. - @VisibleForTesting - static final String SERVICE_PROTOCOL = "adb-tls-pairing"; + @VisibleForTesting static final String SERVICE_PROTOCOL = "adb-tls-pairing"; private final String mServiceType = String.format("_%s._tcp.", SERVICE_PROTOCOL); private int mPort; @@ -352,16 +375,24 @@ public class AdbDebuggingManager { } } - class AdbDebuggingThread extends Thread { + @VisibleForTesting + static class AdbDebuggingThread extends Thread { private boolean mStopped; private LocalSocket mSocket; private OutputStream mOutputStream; private InputStream mInputStream; + private Handler mHandler; + @VisibleForTesting AdbDebuggingThread() { super(TAG); } + @VisibleForTesting + void setHandler(Handler handler) { + mHandler = handler; + } + @Override public void run() { if (DEBUG) Slog.d(TAG, "Entering thread"); @@ -536,7 +567,7 @@ public class AdbDebuggingManager { } } - class AdbConnectionInfo { + private static class AdbConnectionInfo { private String mBssid; private String mSsid; private int mPort; @@ -743,11 +774,14 @@ public class AdbDebuggingManager { // Notification when adbd socket is disconnected. static final int MSG_ADBD_SOCKET_DISCONNECTED = 27; + // === Messages from other parts of the system + private static final int MESSAGE_KEY_FILES_UPDATED = 28; + // === Messages we can send to adbd =========== static final String MSG_DISCONNECT_DEVICE = "DD"; static final String MSG_DISABLE_ADBDWIFI = "DA"; - private AdbKeyStore mAdbKeyStore; + @Nullable @VisibleForTesting AdbKeyStore mAdbKeyStore; // Usb, Wi-Fi transports can be enabled together or separately, so don't break the framework // connection unless all transport types are disconnected. @@ -762,19 +796,19 @@ public class AdbDebuggingManager { } }; - AdbDebuggingHandler(Looper looper) { + /** Constructor that accepts the AdbDebuggingThread to which responses should be sent. */ + @VisibleForTesting + AdbDebuggingHandler(Looper looper, AdbDebuggingThread thread) { super(looper); + mThread = thread; } - /** - * Constructor that accepts the AdbDebuggingThread to which responses should be sent - * and the AdbKeyStore to be used to store the temporary grants. - */ - @TestApi - AdbDebuggingHandler(Looper looper, AdbDebuggingThread thread, AdbKeyStore adbKeyStore) { - super(looper); - mThread = thread; - mAdbKeyStore = adbKeyStore; + /** Initialize the AdbKeyStore so tests can grab mAdbKeyStore immediately. */ + @VisibleForTesting + void initKeyStore() { + if (mAdbKeyStore == null) { + mAdbKeyStore = new AdbKeyStore(); + } } // Show when at least one device is connected. @@ -805,6 +839,7 @@ public class AdbDebuggingManager { registerForAuthTimeChanges(); mThread = new AdbDebuggingThread(); + mThread.setHandler(mHandler); mThread.start(); mAdbKeyStore.updateKeyStore(); @@ -825,8 +860,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.isEmpty()) { for (Map.Entry<String, Integer> entry : mConnectedKeys.entrySet()) { - mAdbKeyStore.setLastConnectionTime(entry.getKey(), - System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(entry.getKey(), mTicker.currentTimeMillis()); } sendPersistKeyStoreMessage(); mConnectedKeys.clear(); @@ -836,9 +870,7 @@ public class AdbDebuggingManager { } public void handleMessage(Message msg) { - if (mAdbKeyStore == null) { - mAdbKeyStore = new AdbKeyStore(); - } + initKeyStore(); switch (msg.what) { case MESSAGE_ADB_ENABLED: @@ -873,7 +905,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.containsKey(key)) { mConnectedKeys.put(key, 1); } - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); } @@ -920,9 +952,7 @@ public class AdbDebuggingManager { mConnectedKeys.clear(); // If the key store has not yet been instantiated then do so now; this avoids // the unnecessary creation of the key store when adb is not enabled. - if (mAdbKeyStore == null) { - mAdbKeyStore = new AdbKeyStore(); - } + initKeyStore(); mWifiConnectedKeys.clear(); mAdbKeyStore.deleteKeyStore(); cancelJobToUpdateAdbKeyStore(); @@ -937,7 +967,8 @@ public class AdbDebuggingManager { alwaysAllow = true; int refcount = mConnectedKeys.get(key) - 1; if (refcount == 0) { - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime( + key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); mConnectedKeys.remove(key); @@ -963,7 +994,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.isEmpty()) { for (Map.Entry<String, Integer> entry : mConnectedKeys.entrySet()) { mAdbKeyStore.setLastConnectionTime(entry.getKey(), - System.currentTimeMillis()); + mTicker.currentTimeMillis()); } sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); @@ -984,7 +1015,7 @@ public class AdbDebuggingManager { } else { mConnectedKeys.put(key, mConnectedKeys.get(key) + 1); } - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); logAdbConnectionChanged(key, AdbProtoEnums.AUTOMATICALLY_ALLOWED, true); @@ -1206,6 +1237,10 @@ public class AdbDebuggingManager { } break; } + case MESSAGE_KEY_FILES_UPDATED: { + mAdbKeyStore.reloadKeyMap(); + break; + } } } @@ -1377,8 +1412,7 @@ public class AdbDebuggingManager { AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); // Add the key into the keystore - mAdbKeyStore.setLastConnectionTime(publicKey, - System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(publicKey, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); } @@ -1449,19 +1483,13 @@ public class AdbDebuggingManager { extras.add(new AbstractMap.SimpleEntry<String, String>("ssid", ssid)); extras.add(new AbstractMap.SimpleEntry<String, String>("bssid", bssid)); int currentUserId = ActivityManager.getCurrentUser(); - UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); - String componentString; - if (userInfo.isAdmin()) { - componentString = Resources.getSystem().getString( - com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); - } else { - componentString = Resources.getSystem().getString( - com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); - } + String componentString = + Resources.getSystem().getString( + R.string.config_customAdbWifiNetworkConfirmationComponent); ComponentName componentName = ComponentName.unflattenFromString(componentString); + UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); if (startConfirmationActivity(componentName, userInfo.getUserHandle(), extras) - || startConfirmationService(componentName, userInfo.getUserHandle(), - extras)) { + || startConfirmationService(componentName, userInfo.getUserHandle(), extras)) { return; } Slog.e(TAG, "Unable to start customAdbWifiNetworkConfirmation[SecondaryUser]Component " @@ -1543,7 +1571,7 @@ public class AdbDebuggingManager { /** * Returns a new File with the specified name in the adb directory. */ - private File getAdbFile(String fileName) { + private static File getAdbFile(String fileName) { File dataDir = Environment.getDataDirectory(); File adbDir = new File(dataDir, ADB_DIRECTORY); @@ -1556,66 +1584,38 @@ public class AdbDebuggingManager { } File getAdbTempKeysFile() { - return getAdbFile(ADB_TEMP_KEYS_FILE); + return mTempKeysFile; } File getUserKeyFile() { - return mTestUserKeyFile == null ? getAdbFile(ADB_KEYS_FILE) : mTestUserKeyFile; + return mUserKeyFile; } - private void writeKey(String key) { - try { - File keyFile = getUserKeyFile(); - - if (keyFile == null) { - return; - } - - FileOutputStream fo = new FileOutputStream(keyFile, true); - fo.write(key.getBytes()); - fo.write('\n'); - fo.close(); - - FileUtils.setPermissions(keyFile.toString(), - FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); - } catch (IOException ex) { - Slog.e(TAG, "Error writing key:" + ex); + private void writeKeys(Iterable<String> keys) { + if (mUserKeyFile == null) { + return; } - } - private void writeKeys(Iterable<String> keys) { - AtomicFile atomicKeyFile = null; + AtomicFile atomicKeyFile = new AtomicFile(mUserKeyFile); + // Note: Do not use a try-with-resources with the FileOutputStream, because AtomicFile + // requires that it's cleaned up with AtomicFile.failWrite(); FileOutputStream fo = null; try { - File keyFile = getUserKeyFile(); - - if (keyFile == null) { - return; - } - - atomicKeyFile = new AtomicFile(keyFile); fo = atomicKeyFile.startWrite(); for (String key : keys) { fo.write(key.getBytes()); fo.write('\n'); } atomicKeyFile.finishWrite(fo); - - FileUtils.setPermissions(keyFile.toString(), - FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); } catch (IOException ex) { Slog.e(TAG, "Error writing keys: " + ex); - if (atomicKeyFile != null) { - atomicKeyFile.failWrite(fo); - } + atomicKeyFile.failWrite(fo); + return; } - } - private void deleteKeyFile() { - File keyFile = getUserKeyFile(); - if (keyFile != null) { - keyFile.delete(); - } + FileUtils.setPermissions( + mUserKeyFile.toString(), + FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); } /** @@ -1745,6 +1745,13 @@ public class AdbDebuggingManager { } /** + * Notify that they key files were updated so the AdbKeyManager reloads the keys. + */ + public void notifyKeyFilesUpdated() { + mHandler.sendEmptyMessage(AdbDebuggingHandler.MESSAGE_KEY_FILES_UPDATED); + } + + /** * Sends a message to the handler to persist the keystore. */ private void sendPersistKeyStoreMessage() { @@ -1778,7 +1785,7 @@ public class AdbDebuggingManager { try { dump.write("keystore", AdbDebuggingManagerProto.KEYSTORE, - FileUtils.readTextFile(getAdbTempKeysFile(), 0, null)); + FileUtils.readTextFile(mTempKeysFile, 0, null)); } catch (IOException e) { Slog.i(TAG, "Cannot read keystore: ", e); } @@ -1792,12 +1799,12 @@ public class AdbDebuggingManager { * ADB_ALLOWED_CONNECTION_TIME setting. */ class AdbKeyStore { - private Map<String, Long> mKeyMap; - private Set<String> mSystemKeys; - private File mKeyFile; private AtomicFile mAtomicKeyFile; - private List<String> mTrustedNetworks; + private final Set<String> mSystemKeys; + private final Map<String, Long> mKeyMap = new HashMap<>(); + private final List<String> mTrustedNetworks = new ArrayList<>(); + private static final int KEYSTORE_VERSION = 1; private static final int MAX_SUPPORTED_KEYSTORE_VERSION = 1; private static final String XML_KEYSTORE_START_TAG = "keyStore"; @@ -1819,26 +1826,22 @@ public class AdbDebuggingManager { public static final long NO_PREVIOUS_CONNECTION = 0; /** - * Constructor that uses the default location for the persistent adb keystore. + * Create an AdbKeyStore instance. + * + * <p>Upon creation, we parse {@link #mTempKeysFile} to determine authorized WiFi APs and + * retrieve the map of stored ADB keys and their last connected times. After that, we read + * the {@link #mUserKeyFile}, and any keys that exist in that file that do not exist in the + * map are added to the map (for backwards compatibility). */ AdbKeyStore() { - init(); - } - - /** - * Constructor that uses the specified file as the location for the persistent adb keystore. - */ - AdbKeyStore(File keyFile) { - mKeyFile = keyFile; - init(); - } - - private void init() { initKeyFile(); - mKeyMap = getKeyMap(); - mTrustedNetworks = getTrustedNetworks(); + readTempKeysFile(); mSystemKeys = getSystemKeysFromFile(SYSTEM_KEY_FILE); - addUserKeysToKeyStore(); + addExistingUserKeysToKeyStore(); + } + + public void reloadKeyMap() { + readTempKeysFile(); } public void addTrustedNetwork(String bssid) { @@ -1877,7 +1880,6 @@ public class AdbDebuggingManager { public void removeKey(String key) { if (mKeyMap.containsKey(key)) { mKeyMap.remove(key); - writeKeys(mKeyMap.keySet()); sendPersistKeyStoreMessage(); } } @@ -1886,12 +1888,9 @@ public class AdbDebuggingManager { * Initializes the key file that will be used to persist the adb grants. */ private void initKeyFile() { - if (mKeyFile == null) { - mKeyFile = getAdbTempKeysFile(); - } - // getAdbTempKeysFile can return null if the adb file cannot be obtained - if (mKeyFile != null) { - mAtomicKeyFile = new AtomicFile(mKeyFile); + // mTempKeysFile can be null if the adb file cannot be obtained + if (mTempKeysFile != null) { + mAtomicKeyFile = new AtomicFile(mTempKeysFile); } } @@ -1932,201 +1931,108 @@ public class AdbDebuggingManager { } /** - * Returns the key map with the keys and last connection times from the key file. + * Update the key map and the trusted networks list with values parsed from the temp keys + * file. */ - private Map<String, Long> getKeyMap() { - Map<String, Long> keyMap = new HashMap<String, Long>(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. + private void readTempKeysFile() { + mKeyMap.clear(); + mTrustedNetworks.clear(); if (mAtomicKeyFile == null) { initKeyFile(); if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return keyMap; + Slog.e( + TAG, + "Unable to obtain the key file, " + mTempKeysFile + ", for reading"); + return; } } if (!mAtomicKeyFile.exists()) { - return keyMap; + return; } try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - // Check for supported keystore version. - XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); - if (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { - Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" - + tagName); - return keyMap; - } + TypedXmlPullParser parser; + try { + parser = Xml.resolvePullParser(keyStream); + XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); + int keystoreVersion = parser.getAttributeInt(null, XML_ATTRIBUTE_VERSION); if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { Slog.e(TAG, "Keystore version=" + keystoreVersion + " not supported (max_supported=" + MAX_SUPPORTED_KEYSTORE_VERSION + ")"); - return keyMap; - } - } - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_ADB_KEY)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); - long connectionTime; - try { - connectionTime = parser.getAttributeLong(null, - XML_ATTRIBUTE_LAST_CONNECTION); - } catch (XmlPullParserException e) { - Slog.e(TAG, - "Caught a NumberFormatException parsing the last connection time: " - + e); - XmlUtils.skipCurrentTag(parser); - continue; + return; } - keyMap.put(key, connectionTime); + } catch (XmlPullParserException e) { + // This could be because the XML document doesn't start with + // XML_KEYSTORE_START_TAG. Try again, instead just starting the document with + // the adbKey tag (the old format). + parser = Xml.resolvePullParser(keyStream); } + readKeyStoreContents(parser); } catch (IOException e) { Slog.e(TAG, "Caught an IOException parsing the XML key file: ", e); } catch (XmlPullParserException e) { - Slog.w(TAG, "Caught XmlPullParserException parsing the XML key file: ", e); - // The file could be written in a format prior to introducing keystore tag. - return getKeyMapBeforeKeystoreVersion(); + Slog.e(TAG, "Caught XmlPullParserException parsing the XML key file: ", e); + } + } + + private void readKeyStoreContents(TypedXmlPullParser parser) + throws XmlPullParserException, IOException { + // This parser is very forgiving. For backwards-compatibility, we simply iterate through + // all the tags in the file, skipping over anything that's not an <adbKey> tag or a + // <wifiAP> tag. Invalid tags (such as ones that don't have a valid "lastConnection" + // attribute) are simply ignored. + while ((parser.next()) != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (XML_TAG_ADB_KEY.equals(tagName)) { + addAdbKeyToKeyMap(parser); + } else if (XML_TAG_WIFI_ACCESS_POINT.equals(tagName)) { + addTrustedNetworkToTrustedNetworks(parser); + } else { + Slog.w(TAG, "Ignoring tag '" + tagName + "'. Not recognized."); + } + XmlUtils.skipCurrentTag(parser); } - return keyMap; } - - /** - * Returns the key map with the keys and last connection times from the key file. - * This implementation was prior to adding the XML_KEYSTORE_START_TAG. - */ - private Map<String, Long> getKeyMapBeforeKeystoreVersion() { - Map<String, Long> keyMap = new HashMap<String, Long>(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. - if (mAtomicKeyFile == null) { - initKeyFile(); - if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return keyMap; - } - } - if (!mAtomicKeyFile.exists()) { - return keyMap; - } - try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - XmlUtils.beginDocument(parser, XML_TAG_ADB_KEY); - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_ADB_KEY)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); - long connectionTime; - try { - connectionTime = parser.getAttributeLong(null, - XML_ATTRIBUTE_LAST_CONNECTION); - } catch (XmlPullParserException e) { - Slog.e(TAG, - "Caught a NumberFormatException parsing the last connection time: " - + e); - XmlUtils.skipCurrentTag(parser); - continue; - } - keyMap.put(key, connectionTime); - } - } catch (IOException | XmlPullParserException e) { - Slog.e(TAG, "Caught an exception parsing the XML key file: ", e); + private void addAdbKeyToKeyMap(TypedXmlPullParser parser) { + String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); + try { + long connectionTime = + parser.getAttributeLong(null, XML_ATTRIBUTE_LAST_CONNECTION); + mKeyMap.put(key, connectionTime); + } catch (XmlPullParserException e) { + Slog.e(TAG, "Error reading adbKey attributes", e); } - return keyMap; } - /** - * Returns the map of trusted networks from the keystore file. - * - * This was implemented in keystore version 1. - */ - private List<String> getTrustedNetworks() { - List<String> trustedNetworks = new ArrayList<String>(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. - if (mAtomicKeyFile == null) { - initKeyFile(); - if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return trustedNetworks; - } - } - if (!mAtomicKeyFile.exists()) { - return trustedNetworks; - } - try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - // Check for supported keystore version. - XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); - if (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { - Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" - + tagName); - return trustedNetworks; - } - int keystoreVersion = parser.getAttributeInt(null, XML_ATTRIBUTE_VERSION); - if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { - Slog.e(TAG, "Keystore version=" + keystoreVersion - + " not supported (max_supported=" - + MAX_SUPPORTED_KEYSTORE_VERSION); - return trustedNetworks; - } - } - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_WIFI_ACCESS_POINT)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String bssid = parser.getAttributeValue(null, XML_ATTRIBUTE_WIFI_BSSID); - trustedNetworks.add(bssid); - } - } catch (IOException | XmlPullParserException | NumberFormatException e) { - Slog.e(TAG, "Caught an exception parsing the XML key file: ", e); - } - return trustedNetworks; + private void addTrustedNetworkToTrustedNetworks(TypedXmlPullParser parser) { + String bssid = parser.getAttributeValue(null, XML_ATTRIBUTE_WIFI_BSSID); + mTrustedNetworks.add(bssid); } /** * Updates the keystore with keys that were previously set to be always allowed before the * connection time of keys was tracked. */ - private void addUserKeysToKeyStore() { - File userKeyFile = getUserKeyFile(); + private void addExistingUserKeysToKeyStore() { + if (mUserKeyFile == null || !mUserKeyFile.exists()) { + return; + } boolean mapUpdated = false; - if (userKeyFile != null && userKeyFile.exists()) { - try (BufferedReader in = new BufferedReader(new FileReader(userKeyFile))) { - long time = System.currentTimeMillis(); - String key; - while ((key = in.readLine()) != null) { - // if the keystore does not contain the key from the user key file then add - // it to the Map with the current system time to prevent it from expiring - // immediately if the user is actively using this key. - if (!mKeyMap.containsKey(key)) { - mKeyMap.put(key, time); - mapUpdated = true; - } + try (BufferedReader in = new BufferedReader(new FileReader(mUserKeyFile))) { + String key; + while ((key = in.readLine()) != null) { + // if the keystore does not contain the key from the user key file then add + // it to the Map with the current system time to prevent it from expiring + // immediately if the user is actively using this key. + if (!mKeyMap.containsKey(key)) { + mKeyMap.put(key, mTicker.currentTimeMillis()); + mapUpdated = true; } - } catch (IOException e) { - Slog.e(TAG, "Caught an exception reading " + userKeyFile + ": " + e); } + } catch (IOException e) { + Slog.e(TAG, "Caught an exception reading " + mUserKeyFile + ": " + e); } if (mapUpdated) { sendPersistKeyStoreMessage(); @@ -2147,7 +2053,9 @@ public class AdbDebuggingManager { if (mAtomicKeyFile == null) { initKeyFile(); if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for writing"); + Slog.e( + TAG, + "Unable to obtain the key file, " + mTempKeysFile + ", for writing"); return; } } @@ -2178,17 +2086,21 @@ public class AdbDebuggingManager { Slog.e(TAG, "Caught an exception writing the key map: ", e); mAtomicKeyFile.failWrite(keyStream); } + writeKeys(mKeyMap.keySet()); } private boolean filterOutOldKeys() { - boolean keysDeleted = false; long allowedTime = getAllowedConnectionTime(); - long systemTime = System.currentTimeMillis(); + if (allowedTime == 0) { + return false; + } + boolean keysDeleted = false; + long systemTime = mTicker.currentTimeMillis(); Iterator<Map.Entry<String, Long>> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = keyMapIterator.next(); long connectionTime = keyEntry.getValue(); - if (allowedTime != 0 && systemTime > (connectionTime + allowedTime)) { + if (systemTime > (connectionTime + allowedTime)) { keyMapIterator.remove(); keysDeleted = true; } @@ -2212,7 +2124,7 @@ public class AdbDebuggingManager { if (allowedTime == 0) { return minExpiration; } - long systemTime = System.currentTimeMillis(); + long systemTime = mTicker.currentTimeMillis(); Iterator<Map.Entry<String, Long>> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = keyMapIterator.next(); @@ -2233,7 +2145,9 @@ public class AdbDebuggingManager { public void deleteKeyStore() { mKeyMap.clear(); mTrustedNetworks.clear(); - deleteKeyFile(); + if (mUserKeyFile != null) { + mUserKeyFile.delete(); + } if (mAtomicKeyFile == null) { return; } @@ -2260,7 +2174,8 @@ public class AdbDebuggingManager { * is set to true the time will be set even if it is older than the previously written * connection time. */ - public void setLastConnectionTime(String key, long connectionTime, boolean force) { + @VisibleForTesting + void setLastConnectionTime(String key, long connectionTime, boolean force) { // Do not set the connection time to a value that is earlier than what was previously // stored as the last connection time unless force is set. if (mKeyMap.containsKey(key) && mKeyMap.get(key) >= connectionTime && !force) { @@ -2271,11 +2186,6 @@ public class AdbDebuggingManager { if (mSystemKeys.contains(key)) { return; } - // if this is the first time the key is being added then write it to the key file as - // well. - if (!mKeyMap.containsKey(key)) { - writeKey(key); - } mKeyMap.put(key, connectionTime); } @@ -2307,12 +2217,8 @@ public class AdbDebuggingManager { long allowedConnectionTime = getAllowedConnectionTime(); // if the allowed connection time is 0 then revert to the previous behavior of always // allowing previously granted adb grants. - if (allowedConnectionTime == 0 || (System.currentTimeMillis() < (lastConnectionTime - + allowedConnectionTime))) { - return true; - } else { - return false; - } + return allowedConnectionTime == 0 + || (mTicker.currentTimeMillis() < (lastConnectionTime + allowedConnectionTime)); } /** @@ -2324,4 +2230,15 @@ public class AdbDebuggingManager { return mTrustedNetworks.contains(bssid); } } + + /** + * A Guava-like interface for getting the current system time. + * + * This allows us to swap a fake ticker in for testing to reduce "Thread.sleep()" calls and test + * for exact expected times instead of random ones. + */ + @VisibleForTesting + interface Ticker { + long currentTimeMillis(); + } } diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index 5d0c732d5f48..55d8dba69626 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -152,6 +152,14 @@ public class AdbService extends IAdbManager.Stub { } @Override + public void notifyKeyFilesUpdated() { + if (mDebuggingManager == null) { + return; + } + mDebuggingManager.notifyKeyFilesUpdated(); + } + + @Override public void startAdbdForTransport(byte transportType) { FgThread.getHandler().sendMessage(obtainMessage( AdbService::setAdbdEnabledForTransport, AdbService.this, true, transportType)); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 43d77ab32371..0040ea9215b3 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -365,6 +365,8 @@ public class AudioService extends IAudioService.Stub private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; + private static final int MSG_ROTATION_UPDATE = 48; + private static final int MSG_FOLD_UPDATE = 49; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), @@ -1251,7 +1253,9 @@ public class AudioService extends IAudioService.Stub intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); if (mMonitorRotation) { - RotationHelper.init(mContext, mAudioHandler); + RotationHelper.init(mContext, mAudioHandler, + rotationParam -> onRotationUpdate(rotationParam), + foldParam -> onFoldUpdate(foldParam)); } intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); @@ -1398,6 +1402,20 @@ public class AudioService extends IAudioService.Stub } //----------------------------------------------------------------- + // rotation/fold updates coming from RotationHelper + void onRotationUpdate(String rotationParameter) { + // use REPLACE as only the last rotation matters + sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, + /*obj*/ rotationParameter, /*delay*/ 0); + } + + void onFoldUpdate(String foldParameter) { + // use REPLACE as only the last fold state matters + sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, + /*obj*/ foldParameter, /*delay*/ 0); + } + + //----------------------------------------------------------------- // monitoring requests for volume range initialization @Override // AudioSystemAdapter.OnVolRangeInitRequestListener public void onVolumeRangeInitRequestFromNative() { @@ -8327,6 +8345,16 @@ public class AudioService extends IAudioService.Stub case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); break; + + case MSG_ROTATION_UPDATE: + // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 + mAudioSystem.setParameters((String) msg.obj); + break; + + case MSG_FOLD_UPDATE: + // fold parameter format: "device_folded=x" where x is one of on, off + mAudioSystem.setParameters((String) msg.obj); + break; } } } diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java index eb8387fe85e5..5cdf58bdd62f 100644 --- a/services/core/java/com/android/server/audio/RotationHelper.java +++ b/services/core/java/com/android/server/audio/RotationHelper.java @@ -21,13 +21,14 @@ import android.hardware.devicestate.DeviceStateManager; import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; -import android.media.AudioSystem; import android.os.Handler; import android.os.HandlerExecutor; import android.util.Log; import android.view.Display; import android.view.Surface; +import java.util.function.Consumer; + /** * Class to handle device rotation events for AudioService, and forward device rotation * and folded state to the audio HALs through AudioSystem. @@ -53,6 +54,10 @@ class RotationHelper { private static AudioDisplayListener sDisplayListener; private static FoldStateListener sFoldStateListener; + /** callback to send rotation updates to AudioSystem */ + private static Consumer<String> sRotationUpdateCb; + /** callback to send folded state updates to AudioSystem */ + private static Consumer<String> sFoldUpdateCb; private static final Object sRotationLock = new Object(); private static final Object sFoldStateLock = new Object(); @@ -67,13 +72,16 @@ class RotationHelper { * - sDisplayListener != null * - sContext != null */ - static void init(Context context, Handler handler) { + static void init(Context context, Handler handler, + Consumer<String> rotationUpdateCb, Consumer<String> foldUpdateCb) { if (context == null) { throw new IllegalArgumentException("Invalid null context"); } sContext = context; sHandler = handler; sDisplayListener = new AudioDisplayListener(); + sRotationUpdateCb = rotationUpdateCb; + sFoldUpdateCb = foldUpdateCb; enable(); } @@ -115,21 +123,26 @@ class RotationHelper { if (DEBUG_ROTATION) { Log.i(TAG, "publishing device rotation =" + rotation + " (x90deg)"); } + String rotationParam; switch (rotation) { case Surface.ROTATION_0: - AudioSystem.setParameters("rotation=0"); + rotationParam = "rotation=0"; break; case Surface.ROTATION_90: - AudioSystem.setParameters("rotation=90"); + rotationParam = "rotation=90"; break; case Surface.ROTATION_180: - AudioSystem.setParameters("rotation=180"); + rotationParam = "rotation=180"; break; case Surface.ROTATION_270: - AudioSystem.setParameters("rotation=270"); + rotationParam = "rotation=270"; break; default: Log.e(TAG, "Unknown device rotation"); + rotationParam = null; + } + if (rotationParam != null) { + sRotationUpdateCb.accept(rotationParam); } } @@ -140,11 +153,13 @@ class RotationHelper { synchronized (sFoldStateLock) { if (sDeviceFold != newFolded) { sDeviceFold = newFolded; + String foldParam; if (newFolded) { - AudioSystem.setParameters("device_folded=on"); + foldParam = "device_folded=on"; } else { - AudioSystem.setParameters("device_folded=off"); + foldParam = "device_folded=off"; } + sFoldUpdateCb.accept(foldParam); } } } diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index 5b26672c7de2..dd44af1b68ee 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -280,18 +280,13 @@ public class SpatializerHelper { } // for both transaural / binaural, we are not forcing enablement as the init() method // could have been called another time after boot in case of audioserver restart - if (mTransauralSupported) { - // not force-enabling as this device might already be in the device list - addCompatibleAudioDevice( - new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), - false /*forceEnable*/); - } - if (mBinauralSupported) { - // not force-enabling as this device might already be in the device list - addCompatibleAudioDevice( - new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""), - false /*forceEnable*/); - } + addCompatibleAudioDevice( + new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), + false /*forceEnable*/); + // not force-enabling as this device might already be in the device list + addCompatibleAudioDevice( + new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""), + false /*forceEnable*/); } catch (RemoteException e) { resetCapabilities(); } finally { @@ -497,10 +492,9 @@ public class SpatializerHelper { synchronized @NonNull List<AudioDeviceAttributes> getCompatibleAudioDevices() { // build unionOf(mCompatibleAudioDevices, mEnabledDevice) - mDisabledAudioDevices ArrayList<AudioDeviceAttributes> compatList = new ArrayList<>(); - for (SADeviceState dev : mSADevices) { - if (dev.mEnabled) { - compatList.add(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, - dev.mDeviceType, dev.mDeviceAddress == null ? "" : dev.mDeviceAddress)); + for (SADeviceState deviceState : mSADevices) { + if (deviceState.mEnabled) { + compatList.add(deviceState.getAudioDeviceAttributes()); } } return compatList; @@ -521,15 +515,15 @@ public class SpatializerHelper { */ private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada, boolean forceEnable) { + if (!isDeviceCompatibleWithSpatializationModes(ada)) { + return; + } loglogi("addCompatibleAudioDevice: dev=" + ada); - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); boolean isInList = false; SADeviceState deviceUpdated = null; // non-null on update. for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { isInList = true; if (forceEnable) { deviceState.mEnabled = true; @@ -539,11 +533,10 @@ public class SpatializerHelper { } } if (!isInList) { - final SADeviceState dev = new SADeviceState(deviceType, - wireless ? ada.getAddress() : ""); - dev.mEnabled = true; - mSADevices.add(dev); - deviceUpdated = dev; + final SADeviceState deviceState = new SADeviceState(ada.getType(), ada.getAddress()); + deviceState.mEnabled = true; + mSADevices.add(deviceState); + deviceUpdated = deviceState; } if (deviceUpdated != null) { onRoutingUpdated(); @@ -574,13 +567,10 @@ public class SpatializerHelper { synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { loglogi("removeCompatibleAudioDevice: dev=" + ada); - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); SADeviceState deviceUpdated = null; // non-null on update. for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { deviceState.mEnabled = false; deviceUpdated = deviceState; break; @@ -602,10 +592,9 @@ public class SpatializerHelper { // if not a wireless device, this value will be overwritten to map the type // to TYPE_BUILTIN_SPEAKER or TYPE_WIRED_HEADPHONES @AudioDeviceInfo.AudioDeviceType int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); // if not a wireless device: find if media device is in the speaker, wired headphones - if (!wireless) { + if (!isWireless(deviceType)) { // is the device type capable of doing SA? if (!mSACapableDeviceTypes.contains(deviceType)) { Log.i(TAG, "Device incompatible with Spatial Audio dev:" + ada); @@ -640,9 +629,7 @@ public class SpatializerHelper { boolean enabled = false; boolean available = false; for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { available = true; enabled = deviceState.mEnabled; break; @@ -652,11 +639,12 @@ public class SpatializerHelper { } private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) { + if (!isDeviceCompatibleWithSpatializationModes(ada)) { + return; + } boolean knownDevice = false; for (SADeviceState deviceState : mSADevices) { - // wireless device so always check address - if (ada.getType() == deviceState.mDeviceType - && ada.getAddress().equals(deviceState.mDeviceAddress)) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { knownDevice = true; break; } @@ -704,13 +692,8 @@ public class SpatializerHelper { if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) { return false; } - - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { return true; } } @@ -719,12 +702,19 @@ public class SpatializerHelper { private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes, @NonNull AudioFormat format, @NonNull AudioDeviceAttributes[] devices) { - final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(devices[0].getType(), + if (isDeviceCompatibleWithSpatializationModes(devices[0])) { + return AudioSystem.canBeSpatialized(attributes, format, devices); + } + return false; + } + + private boolean isDeviceCompatibleWithSpatializationModes(@NonNull AudioDeviceAttributes ada) { + final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(ada.getType(), /*default when type not found*/ SpatializationMode.SPATIALIZER_BINAURAL); if ((modeForDevice == SpatializationMode.SPATIALIZER_BINAURAL && mBinauralSupported) || (modeForDevice == SpatializationMode.SPATIALIZER_TRANSAURAL && mTransauralSupported)) { - return AudioSystem.canBeSpatialized(attributes, format, devices); + return true; } return false; } @@ -1089,13 +1079,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, ignoring setHeadTrackerEnabled to " + enabled + " for " + ada); } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { Log.e(TAG, "Called setHeadTrackerEnabled enabled:" + enabled + " device:" + ada + " on a device without headtracker"); @@ -1109,7 +1094,7 @@ public class SpatializerHelper { } } // check current routing to see if it affects the headtracking mode - if (ROUTING_DEVICES[0].getType() == deviceType + if (ROUTING_DEVICES[0].getType() == ada.getType() && ROUTING_DEVICES[0].getAddress().equals(ada.getAddress())) { setDesiredHeadTrackingMode(enabled ? mDesiredHeadTrackingModeWhenEnabled : Spatializer.HEAD_TRACKING_MODE_DISABLED); @@ -1121,13 +1106,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, hasHeadTracker always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { return deviceState.mHasHeadTracker; } } @@ -1144,13 +1124,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, setHasHeadTracker always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { deviceState.mHasHeadTracker = true; mAudioService.persistSpatialAudioDeviceSettings(); @@ -1168,13 +1143,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, isHeadTrackerEnabled always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { return false; } @@ -1531,7 +1501,7 @@ public class SpatializerHelper { SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @NonNull String address) { mDeviceType = deviceType; - mDeviceAddress = Objects.requireNonNull(address); + mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : ""; } @Override @@ -1599,6 +1569,18 @@ public class SpatializerHelper { return null; } } + + public AudioDeviceAttributes getAudioDeviceAttributes() { + return new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, + mDeviceType, mDeviceAddress == null ? "" : mDeviceAddress); + } + + public boolean matchesAudioDeviceAttributes(AudioDeviceAttributes ada) { + final int deviceType = ada.getType(); + final boolean wireless = isWireless(deviceType); + return (deviceType == mDeviceType) + && (!wireless || ada.getAddress().equals(mDeviceAddress)); + } } /*package*/ synchronized String getSADeviceSettings() { @@ -1619,7 +1601,9 @@ public class SpatializerHelper { // small list, not worth overhead of Arrays.stream(devSettings) for (String setting : devSettings) { SADeviceState devState = SADeviceState.fromPersistedString(setting); - if (devState != null) { + if (devState != null + && isDeviceCompatibleWithSpatializationModes( + devState.getAudioDeviceAttributes())) { mSADevices.add(devState); logDeviceState(devState, "setSADeviceSettings"); } diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index cc49f07dd0e5..41ca13f5d5f5 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -538,13 +538,12 @@ public final class AuthSession implements IBinder.DeathRecipient { void onDialogAnimatedIn() { if (mState != STATE_AUTH_STARTED) { - Slog.w(TAG, "onDialogAnimatedIn, unexpected state: " + mState); + Slog.e(TAG, "onDialogAnimatedIn, unexpected state: " + mState); + return; } mState = STATE_AUTH_STARTED_UI_SHOWING; - startAllPreparedFingerprintSensors(); - mState = STATE_AUTH_STARTED_UI_SHOWING; } void onTryAgainPressed() { diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java index 968146a166ed..ef2931ff5850 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java @@ -20,14 +20,18 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.BiometricConstants; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; +import java.util.function.BooleanSupplier; /** * Contains all the necessary information for a HAL operation. @@ -84,6 +88,8 @@ public class BiometricSchedulerOperation { private final BaseClientMonitor mClientMonitor; @Nullable private final ClientMonitorCallback mClientCallback; + @NonNull + private final BooleanSupplier mIsDebuggable; @Nullable private ClientMonitorCallback mOnStartCallback; @OperationState @@ -99,14 +105,33 @@ public class BiometricSchedulerOperation { this(clientMonitor, callback, STATE_WAITING_IN_QUEUE); } + @VisibleForTesting + BiometricSchedulerOperation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable ClientMonitorCallback callback, + @NonNull BooleanSupplier isDebuggable + ) { + this(clientMonitor, callback, STATE_WAITING_IN_QUEUE, isDebuggable); + } + protected BiometricSchedulerOperation( @NonNull BaseClientMonitor clientMonitor, @Nullable ClientMonitorCallback callback, @OperationState int state ) { + this(clientMonitor, callback, state, Build::isDebuggable); + } + + private BiometricSchedulerOperation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable ClientMonitorCallback callback, + @OperationState int state, + @NonNull BooleanSupplier isDebuggable + ) { mClientMonitor = clientMonitor; mClientCallback = callback; mState = state; + mIsDebuggable = isDebuggable; mCancelWatchdog = () -> { if (!isFinished()) { Slog.e(TAG, "[Watchdog Triggered]: " + this); @@ -144,13 +169,19 @@ public class BiometricSchedulerOperation { * @return if this operation started */ public boolean start(@NonNull ClientMonitorCallback callback) { - checkInState("start", + if (errorWhenNoneOf("start", STATE_WAITING_IN_QUEUE, STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); + STATE_WAITING_IN_QUEUE_CANCELING)) { + return false; + } if (mClientMonitor.getCookie() != 0) { - throw new IllegalStateException("operation requires cookie"); + String err = "operation requires cookie"; + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); + } + Slog.e(TAG, err); } return doStart(callback); @@ -164,16 +195,18 @@ public class BiometricSchedulerOperation { * @return if this operation started */ public boolean startWithCookie(@NonNull ClientMonitorCallback callback, int cookie) { - checkInState("start", - STATE_WAITING_IN_QUEUE, - STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); - if (mClientMonitor.getCookie() != cookie) { Slog.e(TAG, "Mismatched cookie for operation: " + this + ", received: " + cookie); return false; } + if (errorWhenNoneOf("start", + STATE_WAITING_IN_QUEUE, + STATE_WAITING_FOR_COOKIE, + STATE_WAITING_IN_QUEUE_CANCELING)) { + return false; + } + return doStart(callback); } @@ -217,10 +250,12 @@ public class BiometricSchedulerOperation { * immediately abort the operation and notify the client that it has finished unsuccessfully. */ public void abort() { - checkInState("cannot abort a non-pending operation", + if (errorWhenNoneOf("abort", STATE_WAITING_IN_QUEUE, STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); + STATE_WAITING_IN_QUEUE_CANCELING)) { + return; + } if (isHalOperation()) { ((HalClientMonitor<?>) mClientMonitor).unableToStart(); @@ -247,7 +282,9 @@ public class BiometricSchedulerOperation { * the callback used from {@link #start(ClientMonitorCallback)} is used) */ public void cancel(@NonNull Handler handler, @NonNull ClientMonitorCallback callback) { - checkNotInState("cancel", STATE_FINISHED); + if (errorWhenOneOf("cancel", STATE_FINISHED)) { + return; + } final int currentState = mState; if (!isInterruptable()) { @@ -402,21 +439,28 @@ public class BiometricSchedulerOperation { return mClientMonitor; } - private void checkNotInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - throw new IllegalStateException(message + ": illegal state= " + state); + private boolean errorWhenOneOf(String op, @OperationState int... states) { + final boolean isError = ArrayUtils.contains(states, mState); + if (isError) { + String err = op + ": mState must not be " + mState; + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); } + Slog.e(TAG, err); } + return isError; } - private void checkInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - return; + private boolean errorWhenNoneOf(String op, @OperationState int... states) { + final boolean isError = !ArrayUtils.contains(states, mState); + if (isError) { + String err = op + ": mState=" + mState + " must be one of " + Arrays.toString(states); + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); } + Slog.e(TAG, err); } - throw new IllegalStateException(message + ": illegal state= " + mState); + return isError; } @Override diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index d0651ed176cf..d4d3a39c724e 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -348,18 +348,14 @@ class BluetoothRouteProvider { private void addActiveRoute(BluetoothRouteInfo btRoute) { if (btRoute == null) { - if (DEBUG) { - Log.d(TAG, " btRoute is null"); - } + Slog.w(TAG, "addActiveRoute: btRoute is null"); return; } if (DEBUG) { Log.d(TAG, "Adding active route: " + btRoute.route); } if (mActiveRoutes.contains(btRoute)) { - if (DEBUG) { - Log.d(TAG, " btRoute is already added."); - } + Slog.w(TAG, "addActiveRoute: btRoute is already added."); return; } setRouteConnectionState(btRoute, STATE_CONNECTED); @@ -392,6 +388,12 @@ class BluetoothRouteProvider { private void addActiveDevices(BluetoothDevice device) { // Let the given device be the first active device BluetoothRouteInfo activeBtRoute = mBluetoothRoutes.get(device.getAddress()); + // This could happen if ACTION_ACTIVE_DEVICE_CHANGED is sent before + // ACTION_CONNECTION_STATE_CHANGED is sent. + if (activeBtRoute == null) { + activeBtRoute = createBluetoothRoute(device); + mBluetoothRoutes.put(device.getAddress(), activeBtRoute); + } addActiveRoute(activeBtRoute); // A bluetooth route with the same route ID should be added. diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index 098e8f74749c..7d12ede754ef 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -46,7 +46,6 @@ import android.os.UserHandle; import android.util.ArrayMap; import android.util.Slog; import android.view.ContentRecordingSession; -import android.window.WindowContainerToken; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; @@ -433,7 +432,7 @@ public final class MediaProjectionManagerService extends SystemService private IBinder mToken; private IBinder.DeathRecipient mDeathEater; private boolean mRestoreSystemAlertWindow; - private WindowContainerToken mTaskRecordingWindowContainerToken = null; + private IBinder mLaunchCookie = null; MediaProjection(int type, int uid, String packageName, int targetSdkVersion, boolean isPrivileged) { @@ -609,14 +608,13 @@ public final class MediaProjectionManagerService extends SystemService } @Override // Binder call - public void setTaskRecordingWindowContainerToken(WindowContainerToken token) { - // TODO(b/221417940) set the task id to record from sysui, for the package chosen. - mTaskRecordingWindowContainerToken = token; + public void setLaunchCookie(IBinder launchCookie) { + mLaunchCookie = launchCookie; } @Override // Binder call - public WindowContainerToken getTaskRecordingWindowContainerToken() { - return mTaskRecordingWindowContainerToken; + public IBinder getLaunchCookie() { + return mLaunchCookie; } public MediaProjectionInfo getProjectionInfo() { diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index de9102a69a2e..6135fe8acbed 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -340,7 +340,8 @@ public class ZenModeHelper { int newRuleInstanceCount = getCurrentInstanceCount(automaticZenRule.getOwner()) + getCurrentInstanceCount(automaticZenRule.getConfigurationActivity()) + 1; - if (newRuleInstanceCount > RULE_LIMIT_PER_PACKAGE + int newPackageRuleCount = getPackageRuleCount(pkg) + 1; + if (newPackageRuleCount > RULE_LIMIT_PER_PACKAGE || (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount)) { throw new IllegalArgumentException("Rule instance limit exceeded"); } @@ -521,6 +522,23 @@ public class ZenModeHelper { return count; } + // Equivalent method to getCurrentInstanceCount, but for all rules associated with a specific + // package rather than a condition provider service or activity. + private int getPackageRuleCount(String pkg) { + if (pkg == null) { + return 0; + } + int count = 0; + synchronized (mConfig) { + for (ZenRule rule : mConfig.automaticRules.values()) { + if (pkg.equals(rule.getPkg())) { + count++; + } + } + } + return count; + } + public boolean canManageAutomaticZenRule(ZenRule rule) { final int callingUid = Binder.getCallingUid(); if (callingUid == 0 || callingUid == Process.SYSTEM_UID) { diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index 06a54a461d5e..9bfb40fe11f7 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -1540,6 +1540,7 @@ public class ParsingPackageUtils { try { int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION; String minCode = null; + boolean minAssigned = false; int targetVers = ParsingUtils.DEFAULT_TARGET_SDK_VERSION; String targetCode = null; int maxVers = Integer.MAX_VALUE; @@ -1548,9 +1549,11 @@ public class ParsingPackageUtils { if (val != null) { if (val.type == TypedValue.TYPE_STRING && val.string != null) { minCode = val.string.toString(); + minAssigned = !TextUtils.isEmpty(minCode); } else { // If it's not a string, it's an integer. minVers = val.data; + minAssigned = true; } } @@ -1558,7 +1561,7 @@ public class ParsingPackageUtils { if (val != null) { if (val.type == TypedValue.TYPE_STRING && val.string != null) { targetCode = val.string.toString(); - if (minCode == null) { + if (!minAssigned) { minCode = targetCode; } } else { diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index b00d8b47906a..53b8b53e2b6c 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -27,6 +27,7 @@ import android.view.InsetsVisibilities; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.server.notification.NotificationDelegate; @@ -133,7 +134,8 @@ public interface StatusBarManagerInternal { /** @see com.android.internal.statusbar.IStatusBar#onSystemBarAttributesChanged */ void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName); + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails); /** @see com.android.internal.statusbar.IStatusBar#showTransient */ void showTransient(int displayId, @InternalInsetsType int[] types, diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 46e7574e1c8a..71b1bc2e24bc 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -96,6 +96,7 @@ import com.android.internal.statusbar.ISessionListener; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.internal.statusbar.StatusBarIcon; @@ -596,13 +597,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, LetterboxDetails[] letterboxDetails) { getUiState(displayId).setBarAttributes(appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); if (mBar != null) { try { mBar.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); } catch (RemoteException ex) { } } } @@ -1204,17 +1207,20 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private int mImeBackDisposition = 0; private boolean mShowImeSwitcher = false; private IBinder mImeToken = null; + private LetterboxDetails[] mLetterboxDetails; private void setBarAttributes(@Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, + LetterboxDetails[] letterboxDetails) { mAppearance = appearance; mAppearanceRegions = appearanceRegions; mNavbarColorManagedByIme = navbarColorManagedByIme; mBehavior = behavior; mRequestedVisibilities = requestedVisibilities; mPackageName = packageName; + mLetterboxDetails = letterboxDetails; } private void showTransient(@InternalInsetsType int[] types) { @@ -1341,7 +1347,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D state.mImeBackDisposition, state.mShowImeSwitcher, gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken, state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibilities, - state.mPackageName, transientBarTypes); + state.mPackageName, transientBarTypes, state.mLetterboxDetails); } } diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java index b6a413524c5c..452bdf409828 100644 --- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java +++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java @@ -189,6 +189,7 @@ public class TestHarnessModeService extends SystemService { if (adbManager.getAdbTempKeysFile() != null) { writeBytesToFile(persistentData.mAdbTempKeys, adbManager.getAdbTempKeysFile().toPath()); } + adbManager.notifyKeyFilesUpdated(); } private void configureUser() { diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index 622de57a1078..270891fcf421 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -56,6 +56,10 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_T import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__NOT_LETTERBOXED_POSITION; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE; import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED; import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE; import static com.android.internal.util.FrameworkStatsLog.CAMERA_COMPAT_CONTROL_EVENT_REPORTED__EVENT__APPEARED_APPLY_TREATMENT; @@ -1376,7 +1380,7 @@ class ActivityMetricsLogger { return; } - logAppCompatStateInternal(activity, state, packageUid, compatStateInfo); + logAppCompatStateInternal(activity, state, compatStateInfo); } /** @@ -1416,18 +1420,61 @@ class ActivityMetricsLogger { } } if (activityToLog != null && stateToLog != APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE) { - logAppCompatStateInternal(activityToLog, stateToLog, packageUid, compatStateInfo); + logAppCompatStateInternal(activityToLog, stateToLog, compatStateInfo); } } + private static boolean isAppCompateStateChangedToLetterboxed(int state) { + return state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO + || state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION + || state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE; + } + private void logAppCompatStateInternal(@NonNull ActivityRecord activity, int state, - int packageUid, PackageCompatStateInfo compatStateInfo) { + PackageCompatStateInfo compatStateInfo) { compatStateInfo.mLastLoggedState = state; compatStateInfo.mLastLoggedActivity = activity; - FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPAT_STATE_CHANGED, packageUid, state); + int packageUid = activity.info.applicationInfo.uid; + + int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__NOT_LETTERBOXED_POSITION; + if (isAppCompateStateChangedToLetterboxed(state)) { + positionToLog = activity.mLetterboxUiController.getLetterboxPositionForLogging(); + } + FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPAT_STATE_CHANGED, + packageUid, state, positionToLog); + + if (DEBUG_METRICS) { + Slog.i(TAG, String.format("APP_COMPAT_STATE_CHANGED(%s, %s, %s)", + packageUid, state, positionToLog)); + } + } + + /** + * Logs the changing of the letterbox position along with its package UID + */ + void logLetterboxPositionChange(@NonNull ActivityRecord activity, int position) { + int packageUid = activity.info.applicationInfo.uid; + FrameworkStatsLog.write(FrameworkStatsLog.LETTERBOX_POSITION_CHANGED, packageUid, position); + + if (!mPackageUidToCompatStateInfo.contains(packageUid)) { + // There is no last logged activity for this packageUid so we should not log the + // position change as we can only log the position change for the current activity + return; + } + final PackageCompatStateInfo compatStateInfo = mPackageUidToCompatStateInfo.get(packageUid); + final ActivityRecord lastLoggedActivity = compatStateInfo.mLastLoggedActivity; + if (activity != lastLoggedActivity) { + // Only log the position change for the current activity to be consistent with + // findAppCompatStateToLog and ensure that metrics for the state changes are computed + // correctly + return; + } + int state = activity.getAppCompatState(); + logAppCompatStateInternal(activity, state, compatStateInfo); if (DEBUG_METRICS) { - Slog.i(TAG, String.format("APP_COMPAT_STATE_CHANGED(%s, %s)", packageUid, state)); + Slog.i(TAG, String.format("LETTERBOX_POSITION_CHANGED(%s, %s)", + packageUid, position)); } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 359079a1474b..a9b154c869e8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4752,6 +4752,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mPendingRemoteAnimation != null) { mDisplayContent.mAppTransition.overridePendingAppTransitionRemote( mPendingRemoteAnimation); + mTransitionController.setStatusBarTransitionDelay( + mPendingRemoteAnimation.getStatusBarTransitionDelay()); } else { if (mPendingOptions == null || mPendingOptions.getAnimationType() == ANIM_SCENE_TRANSITION) { @@ -7813,11 +7815,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A newParentConfiguration.windowConfiguration.getWindowingMode(); final boolean isFixedOrientationLetterboxAllowed = parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW - || parentWindowingMode == WINDOWING_MODE_FULLSCREEN; + || parentWindowingMode == WINDOWING_MODE_FULLSCREEN + // Switching from PiP to fullscreen. + || (parentWindowingMode == WINDOWING_MODE_PINNED + && resolvedConfig.windowConfiguration.getWindowingMode() + == WINDOWING_MODE_FULLSCREEN); // TODO(b/181207944): Consider removing the if condition and always run // resolveFixedOrientationConfiguration() since this should be applied for all cases. if (isFixedOrientationLetterboxAllowed) { - resolveFixedOrientationConfiguration(newParentConfiguration, parentWindowingMode); + resolveFixedOrientationConfiguration(newParentConfiguration); } if (mCompatDisplayInsets != null) { @@ -8109,8 +8115,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * <p>If letterboxed due to fixed orientation then aspect ratio restrictions are also applied * in this method. */ - private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig, - int windowingMode) { + private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig) { mLetterboxBoundsForFixedOrientationAndAspectRatio = null; mIsEligibleForFixedOrientationLetterbox = false; final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); @@ -8130,11 +8135,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (organizedTf != null && !organizedTf.fillsParent()) { return; } - if (windowingMode == WINDOWING_MODE_PINNED) { - // PiP bounds have higher priority than the requested orientation. Otherwise the - // activity may be squeezed into a small piece. - return; - } final Rect resolvedBounds = getResolvedOverrideConfiguration().windowConfiguration.getBounds(); diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index a452013bf42a..7d84bdf78056 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.os.Bundle; +import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** - * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} + * A class that contains activity intercepting logic for {@link ActivityStarter#execute()} * It's initialized via setStates and interception occurs via the intercept method. * * Note that this class is instantiated when {@link ActivityManagerService} gets created so there @@ -104,6 +105,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; Task mInTask; + TaskFragment mInTaskFragment; ActivityOptions mActivityOptions; ActivityStartInterceptor( @@ -135,15 +137,46 @@ class ActivityStartInterceptor { } private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) { - Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary(); + Bundle bOptions = deferCrossProfileAppsAnimationIfNecessary(); + final TaskFragment taskFragment = getLaunchTaskFragment(); + // If the original intent is going to be embedded, try to forward the embedding TaskFragment + // and its task id to embed back the original intent. + if (taskFragment != null) { + ActivityOptions activityOptions = bOptions != null + ? ActivityOptions.fromBundle(bOptions) + : ActivityOptions.makeBasic(); + activityOptions.setLaunchTaskFragmentToken(taskFragment.getFragmentToken()); + bOptions = activityOptions.toBundle(); + } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId, null /*token*/, null /*resultCode*/, 0 /*requestCode*/, new Intent[] { mIntent }, new String[] { mResolvedType }, - flags, activityOptions); + flags, bOptions); return new IntentSender(target); } + + /** + * A helper function to obtain the targeted {@link TaskFragment} during + * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int, + * ActivityOptions)} if any. + */ + @Nullable + private TaskFragment getLaunchTaskFragment() { + if (mInTaskFragment != null) { + return mInTaskFragment; + } + if (mActivityOptions == null) { + return null; + } + final IBinder taskFragToken = mActivityOptions.getLaunchTaskFragmentToken(); + if (taskFragToken == null) { + return null; + } + return TaskFragment.fromTaskFragmentToken(taskFragToken, mService); + } + /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. @@ -151,7 +184,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, - Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { + Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid, + ActivityOptions activityOptions) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; @@ -161,6 +195,7 @@ class ActivityStartInterceptor { mAInfo = aInfo; mResolvedType = resolvedType; mInTask = inTask; + mInTaskFragment = inTaskFragment; mActivityOptions = activityOptions; if (interceptQuietProfileIfNeeded()) { @@ -332,12 +367,21 @@ class ActivityStartInterceptor { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; + final TaskFragment taskFragment = getLaunchTaskFragment(); // If we are intercepting and there was a task, convert it into an extra for the // ConfirmCredentials intent and unassign it, as otherwise the task will move to // front even if ConfirmCredentials is cancelled. if (mInTask != null) { mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId); mInTask = null; + } else if (taskFragment != null) { + // If the original intent is started to an embedded TaskFragment, append its parent task + // id to extra. It is to embed back the original intent to the TaskFragment with the + // same task. + final Task parentTask = taskFragment.getTask(); + if (parentTask != null) { + mIntent.putExtra(EXTRA_TASK_ID, parentTask.mTaskId); + } } if (mActivityOptions == null) { mActivityOptions = ActivityOptions.makeBasic(); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 960b1bcd5c42..d5362a070d8e 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -79,6 +79,10 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; import android.annotation.NonNull; @@ -132,6 +136,7 @@ import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.LaunchParamsController.LaunchParams; +import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import java.io.PrintWriter; import java.text.DateFormat; @@ -1055,8 +1060,8 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); - if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, - callingUid, checkedOptions)) { + if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, + callingPid, callingUid, checkedOptions)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; @@ -2074,24 +2079,6 @@ class ActivityStarter { } } - if (mInTaskFragment != null && !canEmbedActivity(mInTaskFragment, r, newTask, targetTask)) { - final StringBuilder errorMsg = new StringBuilder("Permission denied: Cannot embed " + r - + " to " + mInTaskFragment.getTask() + ". newTask=" + newTask + ", targetTask= " - + targetTask); - if (newTask && isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, - LAUNCH_SINGLE_INSTANCE_PER_TASK, LAUNCH_SINGLE_TASK)) { - errorMsg.append("\nActivity tries to launch on a new task because the launch mode" - + " is " + launchModeToString(mLaunchMode)); - } else if (newTask && (mLaunchFlags & (FLAG_ACTIVITY_NEW_DOCUMENT - | FLAG_ACTIVITY_NEW_TASK)) != 0) { - errorMsg.append("\nActivity tries to launch on a new task because the launch flags" - + " contains FLAG_ACTIVITY_NEW_DOCUMENT or FLAG_ACTIVITY_NEW_TASK. " - + "mLaunchFlag=" + mLaunchFlags); - } - Slog.e(TAG, errorMsg.toString()); - return START_PERMISSION_DENIED; - } - // Do not start the activity if target display's DWPC does not allow it. // We can't return fatal error code here because it will crash the caller of // startActivity() if they don't catch the exception. We don't expect 3P apps to make @@ -2118,19 +2105,21 @@ class ActivityStarter { } /** - * Return {@code true} if an activity can be embedded to the TaskFragment. + * Returns whether embedding of {@code starting} is allowed. + * * @param taskFragment the TaskFragment for embedding. * @param starting the starting activity. - * @param newTask whether the starting activity is going to be launched on a new task. * @param targetTask the target task for launching activity, which could be different from * the one who hosting the embedding. */ - private boolean canEmbedActivity(@NonNull TaskFragment taskFragment, - @NonNull ActivityRecord starting, boolean newTask, Task targetTask) { + @VisibleForTesting + @EmbeddingCheckResult + static int canEmbedActivity(@NonNull TaskFragment taskFragment, + @NonNull ActivityRecord starting, @NonNull Task targetTask) { final Task hostTask = taskFragment.getTask(); // Not allowed embedding a separate task or without host task. - if (hostTask == null || newTask || targetTask != hostTask) { - return false; + if (hostTask == null || targetTask != hostTask) { + return EMBEDDING_DISALLOWED_NEW_TASK; } return taskFragment.isAllowedToEmbedActivity(starting); @@ -2970,19 +2959,16 @@ class ActivityStarter { mIntentDelivered = true; } + /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */ private void addOrReparentStartingActivity(@NonNull Task task, String reason) { TaskFragment newParent = task; if (mInTaskFragment != null) { - // TODO(b/234351413): remove remaining embedded Task logic. - // mInTaskFragment is created and added to the leaf task by task fragment organizer's - // request. If the task was resolved and different than mInTaskFragment, reparent the - // task to mInTaskFragment for embedding. - if (mInTaskFragment.getTask() != task) { - if (shouldReparentInTaskFragment(task)) { - task.reparent(mInTaskFragment, POSITION_TOP); - } - } else { + int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task); + if (embeddingCheckResult == EMBEDDING_ALLOWED) { newParent = mInTaskFragment; + } else { + // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment. + sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult); } } else { TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; @@ -2994,20 +2980,12 @@ class ActivityStarter { } } if (candidateTf != null && candidateTf.isEmbedded() - && canEmbedActivity(candidateTf, mStartActivity, false /* newTask */, task)) { + && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) { // Use the embedded TaskFragment of the top activity as the new parent if the // activity can be embedded. newParent = candidateTf; } } - // Start Activity to the Task if mStartActivity's min dimensions are not satisfied. - if (newParent.isEmbedded() && newParent.smallerThanMinDimension(mStartActivity)) { - reason += " - MinimumDimensionViolation"; - mService.mWindowOrganizerController.sendMinimumDimensionViolation( - newParent, mStartActivity.getMinDimensions(), mRequest.errorCallbackToken, - reason); - newParent = task; - } if (mStartActivity.getTaskFragment() == null || mStartActivity.getTaskFragment() == newParent) { newParent.addChild(mStartActivity, POSITION_TOP); @@ -3016,16 +2994,41 @@ class ActivityStarter { } } - private boolean shouldReparentInTaskFragment(Task task) { - // The task has not been embedded. We should reparent the task to TaskFragment. - if (!task.isEmbedded()) { - return true; + /** + * Notifies the client side that {@link #mStartActivity} cannot be embedded to + * {@code taskFragment}. + */ + private void sendCanNotEmbedActivityError(TaskFragment taskFragment, + @EmbeddingCheckResult int result) { + final String errMsg; + switch(result) { + case EMBEDDING_DISALLOWED_NEW_TASK: { + errMsg = "Cannot embed " + mStartActivity + " that launched on another task" + + ",mLaunchMode=" + launchModeToString(mLaunchMode) + + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags); + break; + } + case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: { + errMsg = "Cannot embed " + mStartActivity + + ". TaskFragment's bounds:" + taskFragment.getBounds() + + ", minimum dimensions:" + mStartActivity.getMinDimensions(); + break; + } + case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: { + errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity; + break; + } + default: + errMsg = "Unhandled embed result:" + result; + } + if (taskFragment.isOrganized()) { + mService.mWindowOrganizerController.sendTaskFragmentOperationFailure( + taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken, + new SecurityException(errMsg)); + } else { + // If the taskFragment is not organized, just dump error message as warning logs. + Slog.w(TAG, errMsg); } - WindowContainer<?> parent = task.getParent(); - // If the Activity is going to launch on top of embedded Task in the same TaskFragment, - // we don't need to reparent the Task. Otherwise, the embedded Task should reparent to - // another TaskFragment. - return parent.asTaskFragment() != mInTaskFragment; } private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index b76582fcf3b9..eec77898663c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3660,7 +3660,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution) { + public TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution, + boolean takeSnapshotIfNeeded) { mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); final long ident = Binder.clearCallingIdentity(); try { @@ -3674,8 +3675,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } // Don't call this while holding the lock as this operation might hit the disk. - return mWindowManager.mTaskSnapshotController.getSnapshot(taskId, task.mUserId, - true /* restoreFromDisk */, isLowResolution); + TaskSnapshot taskSnapshot = mWindowManager.mTaskSnapshotController.getSnapshot(taskId, + task.mUserId, true /* restoreFromDisk */, isLowResolution); + if (taskSnapshot == null && takeSnapshotIfNeeded) { + taskSnapshot = takeTaskSnapshot(taskId); + } + return taskSnapshot; } finally { Binder.restoreCallingIdentity(ident); } @@ -6648,7 +6653,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public TaskSnapshot getTaskSnapshotBlocking( int taskId, boolean isLowResolution) { - return ActivityTaskManagerService.this.getTaskSnapshot(taskId, isLowResolution); + return ActivityTaskManagerService.this.getTaskSnapshot(taskId, isLowResolution, + false /* takeSnapshotIfNeeded */); } @Override diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java index e3de18b1ebc7..2e1d3b1643ac 100644 --- a/services/core/java/com/android/server/wm/AsyncRotationController.java +++ b/services/core/java/com/android/server/wm/AsyncRotationController.java @@ -357,7 +357,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume * or seamless transformation in a rotated display. */ boolean shouldFreezeInsetsPosition(WindowState w) { - return mTransitionOp == OP_APP_SWITCH && w.mTransitionController.inTransition() + return mTransitionOp != OP_LEGACY && w.mTransitionController.inTransition() && isTargetToken(w.mToken); } diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java index fca4942d4b79..fff7637acc7e 100644 --- a/services/core/java/com/android/server/wm/ContentRecordingController.java +++ b/services/core/java/com/android/server/wm/ContentRecordingController.java @@ -63,6 +63,7 @@ final class ContentRecordingController { */ void setContentRecordingSessionLocked(@Nullable ContentRecordingSession incomingSession, @NonNull WindowManagerService wmService) { + // TODO(b/219761722) handle a null session arriving due to task setup failing if (incomingSession != null && (!ContentRecordingSession.isValid(incomingSession) || ContentRecordingSession.isSameDisplay(mSession, incomingSession))) { // Ignore an invalid session, or a session for the same display as currently recording. diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 96d9d66ab867..288777bdb324 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1610,7 +1610,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (mTransitionController.useShellTransitionsRotation()) { return ROTATION_UNDEFINED; } - if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) { + if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM + || getIgnoreOrientationRequest()) { return ROTATION_UNDEFINED; } if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { @@ -6194,6 +6195,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp .getKeyguardController().isAodShowing(mDisplayId); } + /** + * @return whether the keyguard is occluded on this display + */ + boolean isKeyguardOccluded() { + return mRootWindowContainer.mTaskSupervisor + .getKeyguardController().isDisplayOccluded(mDisplayId); + } + @VisibleForTesting void removeAllTasks() { forAllTasks((t) -> { t.getRootTask().removeChild(t, "removeAllTasks"); }); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index cff8b93ac947..2b359cadb377 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -145,6 +145,7 @@ import com.android.internal.policy.GestureNavigationSettingsObserver; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.SystemBarUtils; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.ScreenshotHelper; import com.android.internal.util.function.TriConsumer; import com.android.internal.view.AppearanceRegion; @@ -2399,7 +2400,7 @@ public class DisplayPolicy { mLastStatusBarAppearanceRegions = statusBarAppearanceRegions; callStatusBarSafely(statusBar -> statusBar.onSystemBarAttributesChanged(displayId, appearance, statusBarAppearanceRegions, isNavbarColorManagedByIme, behavior, - requestedVisibilities, focusedApp)); + requestedVisibilities, focusedApp, new LetterboxDetails[]{})); } private void callStatusBarSafely(Consumer<StatusBarManagerInternal> consumer) { diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 08715b160b9a..91b2fb63a543 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -687,6 +687,24 @@ final class LetterboxConfiguration { } } + /* + * Gets the horizontal position of the letterboxed app window when horizontal reachability is + * enabled. + */ + @LetterboxHorizontalReachabilityPosition + int getLetterboxPositionForHorizontalReachability() { + return mLetterboxPositionForHorizontalReachability; + } + + /* + * Gets the vertical position of the letterboxed app window when vertical reachability is + * enabled. + */ + @LetterboxVerticalReachabilityPosition + int getLetterboxPositionForVerticalReachability() { + return mLetterboxPositionForVerticalReachability; + } + /** Returns a string representing the given {@link LetterboxHorizontalReachabilityPosition}. */ static String letterboxHorizontalReachabilityPositionToString( @LetterboxHorizontalReachabilityPosition int position) { diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index f849d2886ba1..d65276793700 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -21,6 +21,20 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP; +import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER; +import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER; import static com.android.server.wm.ActivityRecord.computeAspectRatio; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -28,6 +42,12 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTypeToString; @@ -259,12 +279,26 @@ final class LetterboxUiController { return; } + int letterboxPositionForHorizontalReachability = mLetterboxConfiguration + .getLetterboxPositionForHorizontalReachability(); if (mLetterbox.getInnerFrame().left > x) { // Moving to the next stop on the left side of the app window: right > center > left. mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop(); + int changeToLog = + letterboxPositionForHorizontalReachability + == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER + ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT + : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER; + logLetterboxPositionChange(changeToLog); } else if (mLetterbox.getInnerFrame().right < x) { // Moving to the next stop on the right side of the app window: left > center > right. mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop(); + int changeToLog = + letterboxPositionForHorizontalReachability + == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER + ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT + : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER; + logLetterboxPositionChange(changeToLog); } // TODO(197549949): Add animation for transition. @@ -280,13 +314,26 @@ final class LetterboxUiController { // Only react to clicks at the top and bottom of the letterboxed app window. return; } - + int letterboxPositionForVerticalReachability = mLetterboxConfiguration + .getLetterboxPositionForVerticalReachability(); if (mLetterbox.getInnerFrame().top > y) { // Moving to the next stop on the top side of the app window: bottom > center > top. mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop(); + int changeToLog = + letterboxPositionForVerticalReachability + == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER + ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP + : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER; + logLetterboxPositionChange(changeToLog); } else if (mLetterbox.getInnerFrame().bottom < y) { // Moving to the next stop on the bottom side of the app window: top > center > bottom. mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop(); + int changeToLog = + letterboxPositionForVerticalReachability + == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER + ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM + : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER; + logLetterboxPositionChange(changeToLog); } // TODO(197549949): Add animation for transition. @@ -577,4 +624,63 @@ final class LetterboxUiController { return "UNKNOWN_REASON"; } + private int letterboxHorizontalReachabilityPositionToLetterboxPosition( + @LetterboxConfiguration.LetterboxHorizontalReachabilityPosition int position) { + switch (position) { + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT; + default: + throw new AssertionError( + "Unexpected letterbox horizontal reachability position type: " + + position); + } + } + + private int letterboxVerticalReachabilityPositionToLetterboxPosition( + @LetterboxConfiguration.LetterboxVerticalReachabilityPosition int position) { + switch (position) { + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP; + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER; + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM: + return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM; + default: + throw new AssertionError( + "Unexpected letterbox vertical reachability position type: " + + position); + } + } + + int getLetterboxPositionForLogging() { + int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION; + if (isHorizontalReachabilityEnabled()) { + int letterboxPositionForHorizontalReachability = getLetterboxConfiguration() + .getLetterboxPositionForHorizontalReachability(); + positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition( + letterboxPositionForHorizontalReachability); + } else if (isVerticalReachabilityEnabled()) { + int letterboxPositionForVerticalReachability = getLetterboxConfiguration() + .getLetterboxPositionForVerticalReachability(); + positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition( + letterboxPositionForVerticalReachability); + } + return positionToLog; + } + + private LetterboxConfiguration getLetterboxConfiguration() { + return mLetterboxConfiguration; + } + + /** + * Logs letterbox position changes via {@link ActivityMetricsLogger#logLetterboxPositionChange}. + */ + private void logLetterboxPositionChange(int letterboxPositionChange) { + mActivityRecord.mTaskSupervisor.getActivityMetricsLogger() + .logLetterboxPositionChange(mActivityRecord, letterboxPositionChange); + } } diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index ad158c7b45b9..ac1a2b17603a 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -331,8 +331,10 @@ class RemoteAnimationController implements DeathRecipient { private void invokeAnimationCancelled(String reason) { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason); + final boolean isKeyguardOccluded = mDisplayContent.isKeyguardOccluded(); + try { - mRemoteAnimationAdapter.getRunner().onAnimationCancelled(); + mRemoteAnimationAdapter.getRunner().onAnimationCancelled(isKeyguardOccluded); } catch (RemoteException e) { Slog.e(TAG, "Failed to notify cancel", e); } diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 61e484aaa5b5..f8a9d4665acc 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -140,6 +140,45 @@ class TaskFragment extends WindowContainer<WindowContainer> { static final boolean SHOW_APP_STARTING_PREVIEW = true; /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can be embedded successfully. + */ + static final int EMBEDDING_ALLOWED = 0; + /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because either the Activity does not allow + * untrusted embedding, and the embedding host app is not trusted. + */ + static final int EMBEDDING_DISALLOWED_UNTRUSTED_HOST = 1; + /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because this taskFragment's bounds are + * {@link #smallerThanMinDimension(ActivityRecord)}. + */ + static final int EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION = 2; + /** + * An embedding check result of + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because the Activity is started on a new task. + */ + static final int EMBEDDING_DISALLOWED_NEW_TASK = 3; + + /** + * Embedding check results of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}. + */ + @IntDef(prefix = {"EMBEDDING_"}, value = { + EMBEDDING_ALLOWED, + EMBEDDING_DISALLOWED_UNTRUSTED_HOST, + EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, + EMBEDDING_DISALLOWED_NEW_TASK, + }) + @interface EmbeddingCheckResult {} + + /** * Indicate that the minimal width/height should use the default value. * * @see #mMinWidth @@ -509,20 +548,29 @@ class TaskFragment extends WindowContainer<WindowContainer> { return false; } - boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) { + @EmbeddingCheckResult + int isAllowedToEmbedActivity(@NonNull ActivityRecord a) { return isAllowedToEmbedActivity(a, mTaskFragmentOrganizerUid); } /** * Checks if the organized task fragment is allowed to have the specified activity, which is - * allowed if an activity allows embedding in untrusted mode, or if the trusted mode can be - * enabled. - * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) + * allowed if an activity allows embedding in untrusted mode, if the trusted mode can be + * enabled, or if the organized task fragment bounds are not + * {@link #smallerThanMinDimension(ActivityRecord)}. + * * @param uid uid of the TaskFragment organizer. + * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) */ - boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a, int uid) { - return isAllowedToEmbedActivityInUntrustedMode(a) - || isAllowedToEmbedActivityInTrustedMode(a, uid); + @EmbeddingCheckResult + int isAllowedToEmbedActivity(@NonNull ActivityRecord a, int uid) { + if (!isAllowedToEmbedActivityInUntrustedMode(a) + && !isAllowedToEmbedActivityInTrustedMode(a, uid)) { + return EMBEDDING_DISALLOWED_UNTRUSTED_HOST; + } else if (smallerThanMinDimension(a)) { + return EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; + } + return EMBEDDING_ALLOWED; } boolean smallerThanMinDimension(@NonNull ActivityRecord activity) { @@ -539,9 +587,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { } final int minWidth = minDimensions.x; final int minHeight = minDimensions.y; - final boolean smaller = taskFragBounds.width() < minWidth + return taskFragBounds.width() < minWidth || taskFragBounds.height() < minHeight; - return smaller; } /** @@ -598,7 +645,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { // The system is trusted to embed other apps securely and for all users. return UserHandle.getAppId(uid) == SYSTEM_UID // Activities from the same UID can be embedded freely by the host. - || uid == a.getUid(); + || a.isUid(uid); } /** diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index 9aff23ddde14..392d4c2f772b 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.window.TaskFragmentOrganizer.putExceptionInBundle; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import android.annotation.IntDef; @@ -235,7 +236,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr + " is not in a task belong to the organizer app."); return; } - if (!task.isAllowedToEmbedActivity(activity, mOrganizerUid)) { + if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED) { Slog.d(TAG, "Reparent activity=" + activity.token + " is not allowed to be embedded."); return; diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 6e84681f0ab5..c5993e1ef4bc 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -36,6 +36,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; +import android.util.ArrayMap; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.Display; @@ -55,7 +56,6 @@ import com.android.internal.util.ArrayUtils; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -94,7 +94,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { * lifecycle order since we may be updating the visibility of task surface controls in a pending * transaction before they are presented to the task org. */ - private class TaskOrganizerCallbacks { + private static class TaskOrganizerCallbacks { final ITaskOrganizer mTaskOrganizer; final Consumer<Runnable> mDeferTaskOrgCallbacksConsumer; @@ -123,7 +123,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } - void onTaskVanished(Task task) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task vanished taskId=%d", task.mTaskId); final RunningTaskInfo taskInfo = task.getTaskInfo(); @@ -173,11 +172,160 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } + /** + * Maintains a list of all the pending events for a given {@link android.window.TaskOrganizer} + */ + static final class TaskOrganizerPendingEventsQueue { + private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>(); + private final TaskOrganizerState mOrganizerState; + private RunningTaskInfo mTmpTaskInfo; + // Pending task events due to layout deferred. + private final ArrayList<PendingTaskEvent> mPendingTaskEvents = new ArrayList<>(); + + TaskOrganizerPendingEventsQueue(TaskOrganizerState taskOrganizerState) { + mOrganizerState = taskOrganizerState; + } + + @VisibleForTesting + public ArrayList<PendingTaskEvent> getPendingEventList() { + return mPendingTaskEvents; + } + + int numPendingTaskEvents() { + return mPendingTaskEvents.size(); + } + + void clearPendingTaskEvents() { + mPendingTaskEvents.clear(); + } + + void addPendingTaskEvent(PendingTaskEvent event) { + mPendingTaskEvents.add(event); + } + + void removePendingTaskEvent(PendingTaskEvent event) { + mPendingTaskEvents.remove(event); + } + + /** + * Removes all the pending task events for the given {@code task}. + * + * @param task + * @return true if a {@link PendingTaskEvent#EVENT_APPEARED} is still pending for the given + * {code task}. + */ + boolean removePendingTaskEvents(Task task) { + boolean foundPendingAppearedEvents = false; + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId) { + // This task is vanished so remove all pending event of it. + mPendingTaskEvents.remove(i); + + if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) { + foundPendingAppearedEvents = true; + } + } + } + return foundPendingAppearedEvents; + } + + @Nullable + private PendingTaskEvent getPendingTaskEvent(Task task, int type) { + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId && type == entry.mEventType) { + return entry; + } + } + return null; + } + + @VisibleForTesting + @Nullable + PendingTaskEvent getPendingLifecycleTaskEvent(Task task) { + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId && entry.isLifecycleEvent()) { + return entry; + } + } + return null; + } + + void dispatchPendingEvents() { + if (mPendingTaskEvents.isEmpty()) { + return; + } + for (int i = 0, n = mPendingTaskEvents.size(); i < n; i++) { + dispatchPendingEvent(mPendingTaskEvents.get(i)); + } + mPendingTaskEvents.clear(); + } + + private void dispatchPendingEvent(PendingTaskEvent event) { + final Task task = event.mTask; + switch (event.mEventType) { + case PendingTaskEvent.EVENT_APPEARED: + if (task.taskAppearedReady()) { + mOrganizerState.mOrganizer.onTaskAppeared(task); + } + break; + case PendingTaskEvent.EVENT_VANISHED: + mOrganizerState.mOrganizer.onTaskVanished(task); + mLastSentTaskInfos.remove(task); + break; + case PendingTaskEvent.EVENT_INFO_CHANGED: + dispatchTaskInfoChanged(event.mTask, event.mForce); + break; + case PendingTaskEvent.EVENT_ROOT_BACK_PRESSED: + mOrganizerState.mOrganizer.onBackPressedOnTaskRoot(task); + break; + } + } + + private void dispatchTaskInfoChanged(Task task, boolean force) { + RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task); + if (mTmpTaskInfo == null) { + mTmpTaskInfo = new RunningTaskInfo(); + } + mTmpTaskInfo.configuration.unset(); + task.fillTaskInfo(mTmpTaskInfo); + + boolean changed = !mTmpTaskInfo + .equalsForTaskOrganizer(lastInfo) + || !configurationsAreEqualForOrganizer( + mTmpTaskInfo.configuration, + lastInfo.configuration); + if (!(changed || force)) { + // mTmpTaskInfo will be reused next time. + return; + } + final RunningTaskInfo newInfo = mTmpTaskInfo; + mLastSentTaskInfos.put(task, + mTmpTaskInfo); + // Since we've stored this, clean up the reference so a new one will be created next + // time. + // Transferring it this way means we only have to construct new RunningTaskInfos when + // they change. + mTmpTaskInfo = null; + + if (task.isOrganized()) { + // Because we defer sending taskAppeared() until the app has drawn, we may receive a + // configuration change before the state actually has the task registered. As such + // we should ignore these change events to the organizer until taskAppeared(). If + // the task was created by the organizer, then we always send the info change. + mOrganizerState.mOrganizer.onTaskInfoChanged(task, newInfo); + } + } + } + @VisibleForTesting class TaskOrganizerState { private final TaskOrganizerCallbacks mOrganizer; private final DeathRecipient mDeathRecipient; private final ArrayList<Task> mOrganizedTasks = new ArrayList<>(); + private final TaskOrganizerPendingEventsQueue mPendingEventsQueue; private final int mUid; TaskOrganizerState(ITaskOrganizer organizer, int uid) { @@ -187,6 +335,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { : mService.mWindowManager.mAnimator::addAfterPrepareSurfacesRunnable; mOrganizer = new TaskOrganizerCallbacks(organizer, deferTaskOrgCallbacksConsumer); mDeathRecipient = new DeathRecipient(organizer); + mPendingEventsQueue = new TaskOrganizerPendingEventsQueue(this); try { organizer.asBinder().linkToDeath(mDeathRecipient, 0); } catch (RemoteException e) { @@ -200,6 +349,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { return mDeathRecipient; } + @VisibleForTesting + TaskOrganizerPendingEventsQueue getPendingEventsQueue() { + return mPendingEventsQueue; + } + /** * Register this task with this state, but doesn't trigger the task appeared callback to * the organizer. @@ -263,8 +417,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // updateTaskOrganizerState should remove the task from the list, but still // check it again to avoid while-loop isn't terminate. if (removeTask(t, t.mRemoveWithTaskOrganizer)) { - TaskOrganizerController.this.onTaskVanishedInternal( - mOrganizer.mTaskOrganizer, t); + TaskOrganizerController.this.onTaskVanishedInternal(this, t); } } if (mService.getTransitionController().isShellTransitionsEnabled()) { @@ -278,8 +431,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } - // Remove organizer state after removing tasks so we get a chance to send - // onTaskVanished. + // Pending events queue for this organizer need to be cleared because this organizer + // has either died or unregistered itself. + mPendingEventsQueue.clearPendingTaskEvents(); mTaskOrganizerStates.remove(mOrganizer.getBinder()); } @@ -320,14 +474,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // List of task organizers by priority private final LinkedList<ITaskOrganizer> mTaskOrganizers = new LinkedList<>(); - private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>(); - private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>(); - // Pending task events due to layout deferred. - private final ArrayList<PendingTaskEvent> mPendingTaskEvents = new ArrayList<>(); + private final ArrayMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new ArrayMap<>(); // Set of organized tasks (by taskId) that dispatch back pressed to their organizers private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet(); - private RunningTaskInfo mTmpTaskInfo; private Consumer<Runnable> mDeferTaskOrgCallbacksConsumer; TaskOrganizerController(ActivityTaskManagerService atm) { @@ -354,11 +504,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mDeferTaskOrgCallbacksConsumer = consumer; } - @VisibleForTesting - ArrayList<PendingTaskEvent> getPendingEventList() { - return mPendingTaskEvents; - } - /** * Register a TaskOrganizer to manage tasks as they enter the a supported windowing mode. */ @@ -592,10 +737,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onTaskAppeared(ITaskOrganizer organizer, Task task) { final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); if (state != null && state.addTask(task)) { - PendingTaskEvent pending = getPendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED); + final TaskOrganizerPendingEventsQueue pendingEvents = + state.mPendingEventsQueue; + PendingTaskEvent pending = pendingEvents.getPendingTaskEvent(task, + PendingTaskEvent.EVENT_APPEARED); if (pending == null) { - pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED); - mPendingTaskEvents.add(pending); + pendingEvents.addPendingTaskEvent(new PendingTaskEvent(task, + PendingTaskEvent.EVENT_APPEARED)); } } } @@ -603,26 +751,25 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onTaskVanished(ITaskOrganizer organizer, Task task) { final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); if (state != null && state.removeTask(task, task.mRemoveWithTaskOrganizer)) { - onTaskVanishedInternal(organizer, task); + onTaskVanishedInternal(state, task); } } - private void onTaskVanishedInternal(ITaskOrganizer organizer, Task task) { - for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { - PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId && entry.mTaskOrg == organizer) { - // This task is vanished so remove all pending event of it. - mPendingTaskEvents.remove(i); - if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) { - // If task appeared callback still pend, ignore this callback too. - return; - } - } + private void onTaskVanishedInternal(TaskOrganizerState organizerState, Task task) { + if (organizerState == null) { + Slog.i(TAG, "cannot send onTaskVanished because organizer state is not " + + "present for this organizer"); + return; } - - PendingTaskEvent pending = - new PendingTaskEvent(task, organizer, PendingTaskEvent.EVENT_VANISHED); - mPendingTaskEvents.add(pending); + TaskOrganizerPendingEventsQueue pendingEventsQueue = + organizerState.mPendingEventsQueue; + boolean hadPendingAppearedEvents = + pendingEventsQueue.removePendingTaskEvents(task); + if (hadPendingAppearedEvents) { + return; + } + pendingEventsQueue.addPendingTaskEvent(new PendingTaskEvent(task, + organizerState.mOrganizer.mTaskOrganizer, PendingTaskEvent.EVENT_VANISHED)); } @Override @@ -690,48 +837,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } void dispatchPendingEvents() { - if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred() - || mPendingTaskEvents.isEmpty()) { + if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) { return; } - - for (int i = 0, n = mPendingTaskEvents.size(); i < n; i++) { - PendingTaskEvent event = mPendingTaskEvents.get(i); - final Task task = event.mTask; - final TaskOrganizerState state; - switch (event.mEventType) { - case PendingTaskEvent.EVENT_APPEARED: - state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder()); - if (state != null && task.taskAppearedReady()) { - state.mOrganizer.onTaskAppeared(task); - } - break; - case PendingTaskEvent.EVENT_VANISHED: - // TaskOrganizerState cannot be used here because it might have already been - // removed. - // The state is removed when an organizer dies or is unregistered. In order to - // send the pending vanished task events, the mTaskOrg from event is used. - // These events should not ideally be sent and will be removed as part of - // b/224812558. - try { - event.mTaskOrg.onTaskVanished(task.getTaskInfo()); - } catch (RemoteException ex) { - Slog.e(TAG, "Exception sending onTaskVanished callback", ex); - } - mLastSentTaskInfos.remove(task); - break; - case PendingTaskEvent.EVENT_INFO_CHANGED: - dispatchTaskInfoChanged(event.mTask, event.mForce); - break; - case PendingTaskEvent.EVENT_ROOT_BACK_PRESSED: - state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder()); - if (state != null) { - state.mOrganizer.onBackPressedOnTaskRoot(task); - } - break; - } + for (int taskOrgIdx = 0; taskOrgIdx < mTaskOrganizerStates.size(); taskOrgIdx++) { + TaskOrganizerState taskOrganizerState = mTaskOrganizerStates.valueAt(taskOrgIdx); + taskOrganizerState.mPendingEventsQueue.dispatchPendingEvents(); } - mPendingTaskEvents.clear(); } void reportImeDrawnOnTask(Task task) { @@ -750,20 +862,30 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // Skip if task still not appeared. return; } - if (force && mPendingTaskEvents.isEmpty()) { + final TaskOrganizerState taskOrganizerState = + mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()); + final TaskOrganizerPendingEventsQueue pendingEventsQueue = + taskOrganizerState.mPendingEventsQueue; + if (pendingEventsQueue == null) { + Slog.i(TAG, "cannot send onTaskInfoChanged because pending events queue is not " + + "present for this organizer"); + return; + } + if (force && pendingEventsQueue.numPendingTaskEvents() == 0) { // There are task-info changed events do not result in // - RootWindowContainer#performSurfacePlacementNoTrace OR // - WindowAnimator#animate // For instance, when an app requesting aspect ratio change when in PiP mode. // To solve this, we directly dispatch the pending event if there are no events queued ( // otherwise, all pending events should be dispatched on next drawn). - dispatchTaskInfoChanged(task, true /* force */); + pendingEventsQueue.dispatchTaskInfoChanged(task, true /* force */); return; } // Defer task info reporting while layout is deferred. This is because layout defer // blocks tend to do lots of re-ordering which can mess up animations in receivers. - PendingTaskEvent pending = getPendingLifecycleTaskEvent(task); + PendingTaskEvent pending = pendingEventsQueue + .getPendingLifecycleTaskEvent(task); if (pending == null) { pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_INFO_CHANGED); } else { @@ -774,45 +896,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { return; } // Remove and add for re-ordering. - mPendingTaskEvents.remove(pending); + pendingEventsQueue.removePendingTaskEvent(pending); } pending.mForce |= force; - mPendingTaskEvents.add(pending); - } - - private void dispatchTaskInfoChanged(Task task, boolean force) { - RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task); - if (mTmpTaskInfo == null) { - mTmpTaskInfo = new RunningTaskInfo(); - } - mTmpTaskInfo.configuration.unset(); - task.fillTaskInfo(mTmpTaskInfo); - - boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo) - || !configurationsAreEqualForOrganizer( - mTmpTaskInfo.configuration, lastInfo.configuration); - if (!(changed || force)) { - // mTmpTaskInfo will be reused next time. - return; - } - final RunningTaskInfo newInfo = mTmpTaskInfo; - mLastSentTaskInfos.put(task, mTmpTaskInfo); - // Since we've stored this, clean up the reference so a new one will be created next time. - // Transferring it this way means we only have to construct new RunningTaskInfos when they - // change. - mTmpTaskInfo = null; - - if (task.isOrganized()) { - // Because we defer sending taskAppeared() until the app has drawn, we may receive a - // configuration change before the state actually has the task registered. As such we - // should ignore these change events to the organizer until taskAppeared(). If the task - // was created by the organizer, then we always send the info change. - final TaskOrganizerState state = mTaskOrganizerStates.get( - task.mTaskOrganizer.asBinder()); - if (state != null) { - state.mOrganizer.onTaskInfoChanged(task, newInfo); - } - } + pendingEventsQueue.addPendingTaskEvent(pending); } @Override @@ -1018,50 +1105,36 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { return false; } + final TaskOrganizerPendingEventsQueue pendingEventsQueue = + mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()) + .mPendingEventsQueue; + if (pendingEventsQueue == null) { + Slog.w(TAG, "cannot get handle BackPressedOnTaskRoot because organizerState is " + + "not present"); + return false; + } PendingTaskEvent pendingVanished = - getPendingTaskEvent(task, PendingTaskEvent.EVENT_VANISHED); + pendingEventsQueue.getPendingTaskEvent(task, + PendingTaskEvent.EVENT_VANISHED); if (pendingVanished != null) { // This task will vanish before this callback so just ignore. return false; } - PendingTaskEvent pending = getPendingTaskEvent( + PendingTaskEvent pending = pendingEventsQueue.getPendingTaskEvent( task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED); if (pending == null) { pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED); } else { // Pending already exist, remove and add for re-ordering. - mPendingTaskEvents.remove(pending); + pendingEventsQueue.removePendingTaskEvent(pending); } - mPendingTaskEvents.add(pending); + pendingEventsQueue.addPendingTaskEvent(pending); mService.mWindowManager.mWindowPlacerLocked.requestTraversal(); return true; } - @Nullable - private PendingTaskEvent getPendingTaskEvent(Task task, int type) { - for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { - PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId && type == entry.mEventType) { - return entry; - } - } - return null; - } - - @VisibleForTesting - @Nullable - PendingTaskEvent getPendingLifecycleTaskEvent(Task task) { - for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { - PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId && entry.isLifecycleEvent()) { - return entry; - } - } - return null; - } - public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println("TaskOrganizerController:"); @@ -1084,4 +1157,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { TaskOrganizerState getTaskOrganizerState(IBinder taskOrganizer) { return mTaskOrganizerStates.get(taskOrganizer); } + + @VisibleForTesting + TaskOrganizerPendingEventsQueue getTaskOrganizerPendingEvents(IBinder taskOrganizer) { + return mTaskOrganizerStates.get(taskOrganizer).mPendingEventsQueue; + } } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 3c0cac0079e8..09f6110b517f 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -149,9 +149,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe final @TransitionType int mType; private int mSyncId = -1; - // Used for tracking a Transition throughout a lifecycle (i.e. from STATE_COLLECTING to - // STATE_FINISHED or STATE_ABORT), and should only be used for testing and debugging. - private int mDebugId = -1; private @TransitionFlags int mFlags; private final TransitionController mController; private final BLASTSyncEngine mSyncEngine; @@ -202,6 +199,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private boolean mNavBarAttachedToApp = false; private int mRecentsDisplayId = INVALID_DISPLAY; + /** The delay for light bar appearance animation. */ + long mStatusBarTransitionDelay; + /** @see #setCanPipOnFinish */ private boolean mCanPipOnFinish = true; @@ -295,11 +295,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe return mSyncId; } - @VisibleForTesting - int getDebugId() { - return mDebugId; - } - @TransitionFlags int getFlags() { return mFlags; @@ -315,6 +310,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe return mFinishTransaction; } + private boolean isCollecting() { + return mState == STATE_COLLECTING || mState == STATE_STARTED; + } + /** Starts collecting phase. Once this starts, all relevant surface operations are sync. */ void startCollecting(long timeoutMs) { if (mState != STATE_PENDING) { @@ -322,7 +321,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } mState = STATE_COLLECTING; mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG); - mDebugId = mSyncId; mController.mTransitionTracer.logState(this); } @@ -353,7 +351,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (mState < STATE_COLLECTING) { throw new IllegalStateException("Transition hasn't started collecting."); } - if (mSyncId < 0) return; + if (!isCollecting()) { + // Too late, transition already started playing, so don't collect. + return; + } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Collecting in transition %d: %s", mSyncId, wc); // "snapshot" all parents (as potential promotion targets). Do this before checking @@ -403,7 +404,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * or waiting until after the animation to close). */ void collectExistenceChange(@NonNull WindowContainer wc) { - if (mSyncId < 0) return; + if (mState >= STATE_PLAYING) { + // Too late to collect. Don't check too-early here since `collect` will check that. + return; + } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Existence Changed in transition %d:" + " %s", mSyncId, wc); collect(wc); @@ -437,7 +441,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe */ void setOverrideAnimation(TransitionInfo.AnimationOptions options, @Nullable IRemoteCallback startCallback, @Nullable IRemoteCallback finishCallback) { - if (mSyncId < 0) return; + if (!isCollecting()) return; mOverrideOptions = options; sendRemoteCallback(mClientAnimationStartCallback); mClientAnimationStartCallback = startCallback; @@ -455,7 +459,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * The transition will wait for all groups to be ready. */ void setReady(WindowContainer wc, boolean ready) { - if (mSyncId < 0) return; + if (!isCollecting() || mSyncId < 0) return; mReadyTracker.setReadyFrom(wc, ready); applyReady(); } @@ -473,7 +477,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * @see ReadyTracker#setAllReady. */ void setAllReady() { - if (mSyncId < 0) return; + if (!isCollecting() || mSyncId < 0) return; mReadyTracker.setAllReady(); applyReady(); } @@ -672,7 +676,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe SurfaceControl.Transaction inputSinkTransaction = null; for (int i = 0; i < mParticipants.size(); ++i) { final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord(); - if (ar == null || !ar.isVisible()) continue; + if (ar == null || !ar.isVisible() || ar.getParent() == null) continue; if (inputSinkTransaction == null) { inputSinkTransaction = new SurfaceControl.Transaction(); } @@ -870,7 +874,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } buildFinishTransaction(mFinishTransaction, info.getRootLeash()); if (mController.getTransitionPlayer() != null) { - mController.dispatchLegacyAppTransitionStarting(info); + mController.dispatchLegacyAppTransitionStarting(info, mStatusBarTransitionDelay); try { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Calling onTransitionReady: %s", info); @@ -889,7 +893,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe // No player registered, so just finish/apply immediately cleanUpOnFailure(); } - mSyncId = -1; mOverrideOptions = null; reportStartReasonsToLogger(); @@ -1614,7 +1617,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } boolean getLegacyIsReady() { - return (mState == STATE_STARTED || mState == STATE_COLLECTING) && mSyncId >= 0; + return isCollecting() && mSyncId >= 0; } static Transition fromBinder(IBinder binder) { diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 6d31e937984e..dbc2c5fb0ce3 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -462,6 +462,12 @@ class TransitionController { }, true /* traverseTopToBottom */); } + /** @see Transition#mStatusBarTransitionDelay */ + void setStatusBarTransitionDelay(long delay) { + if (mCollectingTransition == null) return; + mCollectingTransition.mStatusBarTransitionDelay = delay; + } + /** @see Transition#setOverrideAnimation */ void setOverrideAnimation(TransitionInfo.AnimationOptions options, @Nullable IRemoteCallback startCallback, @Nullable IRemoteCallback finishCallback) { @@ -600,13 +606,14 @@ class TransitionController { } } - void dispatchLegacyAppTransitionStarting(TransitionInfo info) { + void dispatchLegacyAppTransitionStarting(TransitionInfo info, long statusBarTransitionDelay) { final boolean keyguardGoingAway = info.isKeyguardGoingAway(); for (int i = 0; i < mLegacyListeners.size(); ++i) { // TODO(shell-transitions): handle (un)occlude transition. mLegacyListeners.get(i).onAppTransitionStartingLocked(keyguardGoingAway, false /* keyguardOcclude */, 0 /* durationHint */, - SystemClock.uptimeMillis(), AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); + SystemClock.uptimeMillis() + statusBarTransitionDelay, + AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); } } diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java index b1951e038177..c1927d864320 100644 --- a/services/core/java/com/android/server/wm/TransitionTracer.java +++ b/services/core/java/com/android/server/wm/TransitionTracer.java @@ -79,7 +79,7 @@ public class TransitionTracer { final ProtoOutputStream outputStream = new ProtoOutputStream(); final long transitionEntryToken = outputStream.start(TRANSITION); - outputStream.write(ID, transition.getDebugId()); + outputStream.write(ID, transition.getSyncId()); outputStream.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos()); outputStream.write(TRANSITION_TYPE, transition.mType); outputStream.write(STATE, transition.getState()); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 66cc216fd0e2..33c0fe13af11 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2814,6 +2814,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * snapshot from {@link #getFreezeSnapshotTarget()}. */ void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) { + if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) { + // TODO(b/207070762): request shell transition for activityEmbedding change. + return; + } mDisplayContent.prepareAppTransition(TRANSIT_CHANGE); mDisplayContent.mChangingContainers.add(this); // Calculate the relative position in parent container. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 92091bc74766..06d41c0e8d35 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -48,6 +48,7 @@ import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR; import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH; +import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; @@ -288,6 +289,7 @@ import android.view.displayhash.VerifiedDisplayHash; import android.window.ClientWindowFrames; import android.window.ITaskFpsCallback; import android.window.TaskSnapshot; +import android.window.WindowContainerToken; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -2087,7 +2089,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mAttrs.type == TYPE_WALLPAPER) { dc.mWallpaperController.clearLastWallpaperTimeoutTime(); dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; - } else if (win.hasWallpaper()) { + } else if (dc.mWallpaperController.isWallpaperTarget(win)) { dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } @@ -8281,6 +8283,26 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) { synchronized (mGlobalLock) { + // Allow the controller to handle teardown or a non-task session. + if (incomingSession == null + || incomingSession.getContentToRecord() != RECORD_CONTENT_TASK) { + mContentRecordingController.setContentRecordingSessionLocked(incomingSession, + WindowManagerService.this); + return; + } + // For a task session, find the activity identified by the launch cookie. + final WindowContainerToken wct = getTaskWindowContainerTokenForLaunchCookie( + incomingSession.getTokenToRecord()); + if (wct == null) { + Slog.w(TAG, "Handling a new recording session; unable to find the " + + "WindowContainerToken"); + mContentRecordingController.setContentRecordingSessionLocked(null, + WindowManagerService.this); + return; + } + // Replace the launch cookie in the session details with the task's + // WindowContainerToken. + incomingSession.setTokenToRecord(wct.asBinder()); mContentRecordingController.setContentRecordingSessionLocked(incomingSession, WindowManagerService.this); } @@ -8539,6 +8561,38 @@ public class WindowManagerService extends IWindowManager.Stub } /** + * Retrieve the {@link WindowContainerToken} of the task that contains the activity started + * with the given launch cookie. + * + * @param launchCookie the launch cookie set on the {@link ActivityOptions} when starting an + * activity + * @return a token representing the task containing the activity started with the given launch + * cookie, or {@code null} if the token couldn't be found. + */ + @VisibleForTesting + @Nullable + WindowContainerToken getTaskWindowContainerTokenForLaunchCookie(@NonNull IBinder launchCookie) { + // Find the activity identified by the launch cookie. + final ActivityRecord targetActivity = mRoot.getActivity( + activity -> activity.mLaunchCookie == launchCookie); + if (targetActivity == null) { + Slog.w(TAG, "Unable to find the activity for this launch cookie"); + return null; + } + if (targetActivity.getTask() == null) { + Slog.w(TAG, "Unable to find the task for this launch cookie"); + return null; + } + WindowContainerToken taskWindowContainerToken = + targetActivity.getTask().mRemoteToken.toWindowContainerToken(); + if (taskWindowContainerToken == null) { + Slog.w(TAG, "Unable to find the WindowContainerToken for " + targetActivity.getName()); + return null; + } + return taskWindowContainerToken; + } + + /** * You need ALLOW_SLIPPERY_TOUCHES permission to be able to set FLAG_SLIPPERY. */ private int sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid) { diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 1d93c8922d21..97dcb7574e3c 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -46,6 +46,7 @@ import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CON import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -814,7 +815,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); break; } - if (!parent.isAllowedToEmbedActivity(activity)) { + if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) { final Throwable exception = new SecurityException( "The task fragment is not trusted to embed the given activity."); sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); @@ -1057,7 +1058,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } /** A helper method to send minimum dimension violation error to the client. */ - void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions, + private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions, IBinder errorCallbackToken, String reason) { if (taskFragment == null || taskFragment.getTaskFragmentOrganizer() == null) { return; @@ -1672,7 +1673,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub // We are reparenting activities to a new embedded TaskFragment, this operation is only // allowed if the new parent is trusted by all reparent activities. final boolean isEmbeddingDisallowed = oldParent.forAllActivities(activity -> - !newParentTF.isAllowedToEmbedActivity(activity)); + newParentTF.isAllowedToEmbedActivity(activity) == EMBEDDING_ALLOWED); if (isEmbeddingDisallowed) { final Throwable exception = new SecurityException( "The new parent is not trusted to embed the activities."); diff --git a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java index b36aa0617be5..e87dd4b423b2 100644 --- a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java @@ -36,8 +36,6 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; -import com.android.server.FgThread; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -48,6 +46,11 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; @@ -88,6 +91,7 @@ public final class AdbDebuggingManagerTest { private long mOriginalAllowedConnectionTime; private File mAdbKeyXmlFile; private File mAdbKeyFile; + private FakeTicker mFakeTicker; @Before public void setUp() throws Exception { @@ -96,14 +100,25 @@ public final class AdbDebuggingManagerTest { if (mAdbKeyFile.exists()) { mAdbKeyFile.delete(); } - mManager = new AdbDebuggingManager(mContext, ADB_CONFIRM_COMPONENT, mAdbKeyFile); mAdbKeyXmlFile = new File(mContext.getFilesDir(), "test_adb_keys.xml"); if (mAdbKeyXmlFile.exists()) { mAdbKeyXmlFile.delete(); } + + mFakeTicker = new FakeTicker(); + // Set the ticker time to October 22, 2008 (the day the T-Mobile G1 was released) + mFakeTicker.advance(1224658800L); + mThread = new AdbDebuggingThreadTest(); - mKeyStore = mManager.new AdbKeyStore(mAdbKeyXmlFile); - mHandler = mManager.new AdbDebuggingHandler(FgThread.get().getLooper(), mThread, mKeyStore); + mManager = new AdbDebuggingManager( + mContext, ADB_CONFIRM_COMPONENT, mAdbKeyFile, mAdbKeyXmlFile, mThread, mFakeTicker); + + mHandler = mManager.mHandler; + mThread.setHandler(mHandler); + + mHandler.initKeyStore(); + mKeyStore = mHandler.mAdbKeyStore; + mOriginalAllowedConnectionTime = mKeyStore.getAllowedConnectionTime(); mBlockingQueue = new ArrayBlockingQueue<>(1); } @@ -122,7 +137,7 @@ public final class AdbDebuggingManagerTest { private void setAllowedConnectionTime(long connectionTime) { Settings.Global.putLong(mContext.getContentResolver(), Settings.Global.ADB_ALLOWED_CONNECTION_TIME, connectionTime); - }; + } @Test public void testAllowNewKeyOnce() throws Exception { @@ -158,20 +173,15 @@ public final class AdbDebuggingManagerTest { // Allow a connection from a new key with the 'Always allow' option selected. runAdbTest(TEST_KEY_1, true, true, false); - // Get the last connection time for the currently connected key to verify that it is updated - // after the disconnect. - long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - - // Sleep for a small amount of time to ensure a difference can be observed in the last - // connection time after a disconnect. - Thread.sleep(10); + // Advance the clock by 10ms to ensure there's a difference + mFakeTicker.advance(10 * 1_000_000); // Send the disconnect message for the currently connected key to trigger an update of the // last connection time. disconnectKey(TEST_KEY_1); - assertNotEquals( + assertEquals( "The last connection time was not updated after the disconnect", - lastConnectionTime, + mFakeTicker.currentTimeMillis(), mKeyStore.getLastConnectionTime(TEST_KEY_1)); } @@ -244,8 +254,8 @@ public final class AdbDebuggingManagerTest { // Get the current last connection time for comparison after the scheduled job is run long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - // Sleep a small amount of time to ensure that the updated connection time changes - Thread.sleep(10); + // Advance a small amount of time to ensure that the updated connection time changes + mFakeTicker.advance(10); // Send a message to the handler to update the last connection time for the active key updateKeyStore(); @@ -269,13 +279,13 @@ public final class AdbDebuggingManagerTest { persistKeyStore(); assertTrue( "The key with the 'Always allow' option selected was not persisted in the keystore", - mManager.new AdbKeyStore(mAdbKeyXmlFile).isKeyAuthorized(TEST_KEY_1)); + mManager.new AdbKeyStore().isKeyAuthorized(TEST_KEY_1)); // Get the current last connection time to ensure it is updated in the persisted keystore. long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - // Sleep a small amount of time to ensure the last connection time is updated. - Thread.sleep(10); + // Advance a small amount of time to ensure the last connection time is updated. + mFakeTicker.advance(10); // Send a message to the handler to update the last connection time for the active key. updateKeyStore(); @@ -286,7 +296,7 @@ public final class AdbDebuggingManagerTest { assertNotEquals( "The last connection time in the key file was not updated after the update " + "connection time message", lastConnectionTime, - mManager.new AdbKeyStore(mAdbKeyXmlFile).getLastConnectionTime(TEST_KEY_1)); + mManager.new AdbKeyStore().getLastConnectionTime(TEST_KEY_1)); // Verify that the key is in the adb_keys file assertTrue("The key was not in the adb_keys file after persisting the keystore", isKeyInFile(TEST_KEY_1, mAdbKeyFile)); @@ -327,8 +337,8 @@ public final class AdbDebuggingManagerTest { // Set the allowed window to a small value to ensure the time is beyond the allowed window. setAllowedConnectionTime(1); - // Sleep for a small amount of time to exceed the allowed window. - Thread.sleep(10); + // Advance a small amount of time to exceed the allowed window. + mFakeTicker.advance(10); // The AdbKeyStore has a method to get the time of the next key expiration to ensure the // scheduled job runs at the time of the next expiration or after 24 hours, whichever occurs @@ -478,9 +488,12 @@ public final class AdbDebuggingManagerTest { // Set the current expiration time to a minute from expiration and verify this new value is // returned. final long newExpirationTime = 60000; - mKeyStore.setLastConnectionTime(TEST_KEY_1, - System.currentTimeMillis() - Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME - + newExpirationTime, true); + mKeyStore.setLastConnectionTime( + TEST_KEY_1, + mFakeTicker.currentTimeMillis() + - Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME + + newExpirationTime, + true); expirationTime = mKeyStore.getNextExpirationTime(); if (Math.abs(expirationTime - newExpirationTime) > epsilon) { fail("The expiration time for a key about to expire, " + expirationTime @@ -525,7 +538,7 @@ public final class AdbDebuggingManagerTest { // Get the last connection time for the key to verify that it is updated when the connected // key message is sent. long connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); mHandler.obtainMessage(AdbDebuggingManager.AdbDebuggingHandler.MESSAGE_ADB_CONNECTED_KEY, TEST_KEY_1).sendToTarget(); flushHandlerQueue(); @@ -536,7 +549,7 @@ public final class AdbDebuggingManagerTest { // Verify that the scheduled job updates the connection time of the key. connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for the key must be updated when the update keystore message" @@ -545,7 +558,7 @@ public final class AdbDebuggingManagerTest { // Verify that the connection time is updated when the key is disconnected. connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); disconnectKey(TEST_KEY_1); assertNotEquals( "The connection time for the key must be updated when the disconnected message is" @@ -628,11 +641,11 @@ public final class AdbDebuggingManagerTest { setAllowedConnectionTime(Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME); // The untracked keys should be added to the keystore as part of the constructor. - AdbDebuggingManager.AdbKeyStore adbKeyStore = mManager.new AdbKeyStore(mAdbKeyXmlFile); + AdbDebuggingManager.AdbKeyStore adbKeyStore = mManager.new AdbKeyStore(); // Verify that the connection time for each test key is within a small value of the current // time. - long time = System.currentTimeMillis(); + long time = mFakeTicker.currentTimeMillis(); for (String key : testKeys) { long connectionTime = adbKeyStore.getLastConnectionTime(key); if (Math.abs(time - connectionTime) > epsilon) { @@ -651,11 +664,11 @@ public final class AdbDebuggingManagerTest { runAdbTest(TEST_KEY_1, true, true, false); runAdbTest(TEST_KEY_2, true, true, false); - // Sleep a small amount of time to ensure the connection time is updated by the scheduled + // Advance a small amount of time to ensure the connection time is updated by the scheduled // job. long connectionTime1 = mKeyStore.getLastConnectionTime(TEST_KEY_1); long connectionTime2 = mKeyStore.getLastConnectionTime(TEST_KEY_2); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for test key 1 must be updated after the scheduled job runs", @@ -669,7 +682,7 @@ public final class AdbDebuggingManagerTest { disconnectKey(TEST_KEY_2); connectionTime1 = mKeyStore.getLastConnectionTime(TEST_KEY_1); connectionTime2 = mKeyStore.getLastConnectionTime(TEST_KEY_2); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for test key 1 must be updated after another key is " @@ -686,8 +699,6 @@ public final class AdbDebuggingManagerTest { // to clear the adb authorizations when adb is disabled after a boot a NullPointerException // was thrown as deleteKeyStore is invoked against the key store. This test ensures the // key store can be successfully cleared when adb is disabled. - mHandler = mManager.new AdbDebuggingHandler(FgThread.get().getLooper()); - clearKeyStore(); } @@ -723,6 +734,9 @@ public final class AdbDebuggingManagerTest { // Now remove one of the keys and make sure the other key is still there mKeyStore.removeKey(TEST_KEY_1); + // Wait for the handler queue to receive the MESSAGE_ADB_PERSIST_KEYSTORE + flushHandlerQueue(); + assertFalse("The key was still in the adb_keys file after removing the key", isKeyInFile(TEST_KEY_1, mAdbKeyFile)); assertTrue("The key was not in the adb_keys file after removing a different key", @@ -730,6 +744,95 @@ public final class AdbDebuggingManagerTest { } @Test + public void testAdbKeyStore_addDuplicateKey_doesNotAddDuplicateToAdbKeyFile() throws Exception { + setAllowedConnectionTime(0); + + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + assertEquals("adb_keys contains duplicate keys", 1, adbKeyFileKeys(mAdbKeyFile).size()); + } + + @Test + public void testAdbKeyStore_adbTempKeysFile_readsLastConnectionTimeFromXml() throws Exception { + long insertTime = mFakeTicker.currentTimeMillis(); + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + mFakeTicker.advance(10); + AdbDebuggingManager.AdbKeyStore newKeyStore = mManager.new AdbKeyStore(); + + assertEquals( + "KeyStore not populated from the XML file.", + insertTime, + newKeyStore.getLastConnectionTime(TEST_KEY_1)); + } + + @Test + public void test_notifyKeyFilesUpdated_filesDeletedRemovesPreviouslyAddedKey() + throws Exception { + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + Files.delete(mAdbKeyXmlFile.toPath()); + Files.delete(mAdbKeyFile.toPath()); + + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + assertFalse( + "Key is authorized after reloading deleted key files. Was state preserved?", + mKeyStore.isKeyAuthorized(TEST_KEY_1)); + } + + @Test + public void test_notifyKeyFilesUpdated_newKeyIsAuthorized() throws Exception { + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + // Back up the existing key files + Path tempXmlFile = Files.createTempFile("adbKeyXmlFile", ".tmp"); + Path tempAdbKeysFile = Files.createTempFile("adb_keys", ".tmp"); + Files.copy(mAdbKeyXmlFile.toPath(), tempXmlFile, StandardCopyOption.REPLACE_EXISTING); + Files.copy(mAdbKeyFile.toPath(), tempAdbKeysFile, StandardCopyOption.REPLACE_EXISTING); + + // Delete the existing key files + Files.delete(mAdbKeyXmlFile.toPath()); + Files.delete(mAdbKeyFile.toPath()); + + // Notify the manager that adb key files have changed. + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + // Copy the files back + Files.copy(tempXmlFile, mAdbKeyXmlFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(tempAdbKeysFile, mAdbKeyFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + + // Tell the manager that the key files have changed. + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + assertTrue( + "Key is not authorized after reloading key files.", + mKeyStore.isKeyAuthorized(TEST_KEY_1)); + } + + @Test + public void testAdbKeyStore_adbWifiConnect_storesBssidWhenAlwaysAllow() throws Exception { + String trustedNetwork = "My Network"; + mKeyStore.addTrustedNetwork(trustedNetwork); + persistKeyStore(); + + AdbDebuggingManager.AdbKeyStore newKeyStore = mManager.new AdbKeyStore(); + + assertTrue( + "Persisted trusted network not found in new keystore instance.", + newKeyStore.isTrustedNetwork(trustedNetwork)); + } + + @Test public void testIsValidMdnsServiceName() { // Longer than 15 characters assertFalse(isValidMdnsServiceName("abcd1234abcd1234")); @@ -1030,28 +1133,27 @@ public final class AdbDebuggingManagerTest { if (key == null) { return false; } + return adbKeyFileKeys(keyFile).contains(key); + } + + private static List<String> adbKeyFileKeys(File keyFile) throws Exception { + List<String> keys = new ArrayList<>(); if (keyFile.exists()) { try (BufferedReader in = new BufferedReader(new FileReader(keyFile))) { String currKey; while ((currKey = in.readLine()) != null) { - if (key.equals(currKey)) { - return true; - } + keys.add(currKey); } } } - return false; + return keys; } /** * Helper class that extends AdbDebuggingThread to receive the response from AdbDebuggingManager * indicating whether the key should be allowed to connect. */ - class AdbDebuggingThreadTest extends AdbDebuggingManager.AdbDebuggingThread { - AdbDebuggingThreadTest() { - mManager.super(); - } - + private class AdbDebuggingThreadTest extends AdbDebuggingManager.AdbDebuggingThread { @Override public void sendResponse(String msg) { TestResult result = new TestResult(TestResult.RESULT_RESPONSE_RECEIVED, msg); @@ -1091,4 +1193,17 @@ public final class AdbDebuggingManagerTest { return "{mReturnCode = " + mReturnCode + ", mMessage = " + mMessage + "}"; } } + + private static class FakeTicker implements AdbDebuggingManager.Ticker { + private long mCurrentTime; + + private void advance(long milliseconds) { + mCurrentTime += milliseconds; + } + + @Override + public long currentTimeMillis() { + return mCurrentTime; + } + } } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java index 25cf8a86baad..e95924ad7109 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java @@ -20,7 +20,9 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_NEGATIVE; -import static com.android.server.biometrics.BiometricServiceStateProto.*; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED_UI_SHOWING; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -32,6 +34,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -280,6 +284,43 @@ public class AuthSessionTest { } @Test + public void testOnDialogAnimatedInDoesNothingDuringInvalidState() throws Exception { + setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); + final long operationId = 123; + final int userId = 10; + + final AuthSession session = createAuthSession(mSensors, + false /* checkDevicePolicyManager */, + Authenticators.BIOMETRIC_STRONG, + TEST_REQUEST_ID, + operationId, + userId); + final IBiometricAuthenticator impl = session.mPreAuthInfo.eligibleSensors.get(0).impl; + + session.goToInitialState(); + for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) { + assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState()); + session.onCookieReceived( + session.mPreAuthInfo.eligibleSensors.get(sensor.id).getCookie()); + } + assertTrue(session.allCookiesReceived()); + assertEquals(STATE_AUTH_STARTED, session.getState()); + verify(impl, never()).startPreparedClient(anyInt()); + + // First invocation should start the client monitor. + session.onDialogAnimatedIn(); + assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState()); + verify(impl).startPreparedClient(anyInt()); + + // Subsequent invocations should not start the client monitor again. + session.onDialogAnimatedIn(); + session.onDialogAnimatedIn(); + session.onDialogAnimatedIn(); + assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState()); + verify(impl, times(1)).startPreparedClient(anyInt()); + } + + @Test public void testCancelAuthentication_whenStateAuthCalled_invokesCancel() throws RemoteException { testInvokesCancel(session -> session.onCancelAuthSession(false /* force */)); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java index c17347320f52..9e9d70332f00 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java @@ -80,11 +80,14 @@ public class BiometricSchedulerOperationTest { private Handler mHandler; private BiometricSchedulerOperation mOperation; + private boolean mIsDebuggable; @Before public void setUp() { mHandler = new Handler(TestableLooper.get(this).getLooper()); - mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback); + mIsDebuggable = false; + mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback, + () -> mIsDebuggable); } @Test @@ -126,6 +129,34 @@ public class BiometricSchedulerOperationTest { } @Test + public void testSecondStartWithCookieCrashesWhenDebuggable() { + final int cookie = 5; + mIsDebuggable = true; + when(mClientMonitor.getCookie()).thenReturn(cookie); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(started).isTrue(); + + assertThrows(IllegalStateException.class, + () -> mOperation.startWithCookie(mOnStartCallback, cookie)); + } + + @Test + public void testSecondStartWithCookieFailsNicelyWhenNotDebuggable() { + final int cookie = 5; + mIsDebuggable = false; + when(mClientMonitor.getCookie()).thenReturn(cookie); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(started).isTrue(); + + final boolean startedAgain = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(startedAgain).isFalse(); + } + + @Test public void startsWhenReadyAndHalAvailable() { when(mClientMonitor.getCookie()).thenReturn(0); when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); @@ -170,7 +201,34 @@ public class BiometricSchedulerOperationTest { } @Test + public void secondStartCrashesWhenDebuggable() { + mIsDebuggable = true; + when(mClientMonitor.getCookie()).thenReturn(0); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.start(mOnStartCallback); + assertThat(started).isTrue(); + + assertThrows(IllegalStateException.class, () -> mOperation.start(mOnStartCallback)); + } + + @Test + public void secondStartFailsNicelyWhenNotDebuggable() { + mIsDebuggable = false; + when(mClientMonitor.getCookie()).thenReturn(0); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.start(mOnStartCallback); + assertThat(started).isTrue(); + + final boolean startedAgain = mOperation.start(mOnStartCallback); + assertThat(startedAgain).isFalse(); + } + + @Test public void doesNotStartWithCookie() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getCookie()).thenReturn(9); assertThrows(IllegalStateException.class, () -> mOperation.start(mock(ClientMonitorCallback.class))); @@ -178,6 +236,8 @@ public class BiometricSchedulerOperationTest { @Test public void cannotRestart() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.start(mOnStartCallback); @@ -188,6 +248,8 @@ public class BiometricSchedulerOperationTest { @Test public void abortsNotRunning() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.abort(); @@ -200,7 +262,8 @@ public class BiometricSchedulerOperationTest { } @Test - public void cannotAbortRunning() { + public void abortCrashesWhenDebuggableIfOperationIsRunning() { + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.start(mOnStartCallback); @@ -209,6 +272,16 @@ public class BiometricSchedulerOperationTest { } @Test + public void abortFailsNicelyWhenNotDebuggableIfOperationIsRunning() { + mIsDebuggable = false; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.start(mOnStartCallback); + + mOperation.abort(); + } + + @Test public void cancel() { when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); @@ -254,6 +327,30 @@ public class BiometricSchedulerOperationTest { } @Test + public void cancelCrashesWhenDebuggableIfOperationIsFinished() { + mIsDebuggable = true; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.abort(); + assertThat(mOperation.isFinished()).isTrue(); + + final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class); + assertThrows(IllegalStateException.class, () -> mOperation.cancel(mHandler, cancelCb)); + } + + @Test + public void cancelFailsNicelyWhenNotDebuggableIfOperationIsFinished() { + mIsDebuggable = false; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.abort(); + assertThat(mOperation.isFinished()).isTrue(); + + final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class); + mOperation.cancel(mHandler, cancelCb); + } + + @Test public void markCanceling() { when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index fd1536c5c0f1..4550b56f6fd0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -1622,7 +1622,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(si), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); + // We need the package name to be something that's not "android" so there aren't any + // existing rules under that package. + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); assertNotNull(id); } try { @@ -1632,12 +1634,41 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { // yay } + } + @Test + public void testAddAutomaticZenRule_beyondSystemLimit_differentComponents() { + // Make sure the system limit is enforced per-package even with different component provider + // names. + for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) { + ScheduleInfo si = new ScheduleInfo(); + si.startHour = i; + AutomaticZenRule zenRule = new AutomaticZenRule("name" + i, + null, + new ComponentName("android", "ScheduleConditionProvider" + i), + ZenModeConfig.toScheduleConditionId(si), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); + assertNotNull(id); + } + try { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName("android", "ScheduleConditionProviderFinal"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); + fail("allowed too many rules to be created"); + } catch (IllegalArgumentException e) { + // yay + } } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index cfeaf850da03..0c3b270518cf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -29,6 +29,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; +import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; +import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; @@ -182,6 +184,10 @@ public class ActivityRecordTests extends WindowTestsBase { private final String mPackageName = getInstrumentation().getTargetContext().getPackageName(); + private static final int ORIENTATION_CONFIG_CHANGES = + CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT | CONFIG_SCREEN_SIZE + | CONFIG_SMALLEST_SCREEN_SIZE; + @Before public void setUp() throws Exception { setBooted(mAtm); @@ -487,7 +493,7 @@ public class ActivityRecordTests extends WindowTestsBase { public void testSetRequestedOrientationUpdatesConfiguration() throws Exception { final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true) - .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT) + .setConfigChanges(ORIENTATION_CONFIG_CHANGES) .build(); activity.setState(RESUMED, "Testing"); @@ -710,7 +716,7 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true) .setLaunchTaskBehind(true) - .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT) + .setConfigChanges(ORIENTATION_CONFIG_CHANGES) .build(); final Task task = activity.getTask(); activity.setState(STOPPED, "Testing"); @@ -779,7 +785,7 @@ public class ActivityRecordTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }, 0, 0)); activity.updateOptionsLocked(opts); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 73e409abf0c1..1575336600b4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest { .thenReturn(PLATFORM_PACKAGE_NAME); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the admin support intent assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent); @@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest { final String suspendingPackage = "com.test.suspending.package"; final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // Check intent parameters assertEquals(dialogInfo, @@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)) .thenReturn(false); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME) .filterEquals(mInterceptor.mIntent)); @@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest { when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true); // THEN calling intercept returns true - mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null); + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); // THEN the returned intent is the quiet mode intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); @@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest { .thenReturn("This app is bad"); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the harmful app warning intent assertEquals(HarmfulAppWarningActivity.class.getName(), @@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest { // GIVEN that none of the interception conditions are met // THEN calling intercept returns false - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } public void addMockInterceptorCallback( @@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } @@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest { public void testInterceptionCallback_singleCallbackReturnsNull() { addMockInterceptorCallback(null, null); - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } @Test @@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest { addMockInterceptorCallback(null, null); addMockInterceptorCallback(new Intent("android.test.second"), null); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 1176786eacc7..c78bc59612d4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -37,6 +37,7 @@ import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; +import static android.content.pm.ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; @@ -52,6 +53,11 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.wm.ActivityStarter.canEmbedActivity; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -59,6 +65,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -87,6 +94,7 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.service.voice.IVoiceInteractionSession; import android.util.Pair; +import android.util.Size; import android.view.Gravity; import android.window.TaskFragmentOrganizerToken; @@ -1171,6 +1179,7 @@ public class ActivityStarterTests extends WindowTestsBase { null /* inTask */, taskFragment); assertFalse(taskFragment.hasChild()); + assertNotNull("Target record must be started on Task.", targetRecord.getParent().asTask()); } @Test @@ -1341,6 +1350,58 @@ public class ActivityStarterTests extends WindowTestsBase { any()); } + @Test + public void testCanEmbedActivity() { + final Size minDimensions = new Size(1000, 1000); + final WindowLayout windowLayout = new WindowLayout(0, 0, 0, 0, 0, + minDimensions.getWidth(), minDimensions.getHeight()); + final ActivityRecord starting = new ActivityBuilder(mAtm) + .setUid(UNIMPORTANT_UID) + .setWindowLayout(windowLayout) + .build(); + + // Task fragment hasn't attached to a task yet. Start activity to a new task. + TaskFragment taskFragment = new TaskFragmentBuilder(mAtm).build(); + final Task task = new TaskBuilder(mSupervisor).build(); + + assertEquals(EMBEDDING_DISALLOWED_NEW_TASK, + canEmbedActivity(taskFragment, starting, task)); + + // Starting activity is going to be started on a task different from task fragment's parent + // task. Start activity to a new task. + task.addChild(taskFragment, POSITION_TOP); + final Task newTask = new TaskBuilder(mSupervisor).build(); + + assertEquals(EMBEDDING_DISALLOWED_NEW_TASK, + canEmbedActivity(taskFragment, starting, newTask)); + + // Make task fragment bounds exceed task bounds. + final Rect taskBounds = task.getBounds(); + taskFragment.setBounds(taskBounds.left, taskBounds.top, taskBounds.right + 1, + taskBounds.bottom + 1); + + assertEquals(EMBEDDING_DISALLOWED_UNTRUSTED_HOST, + canEmbedActivity(taskFragment, starting, task)); + + taskFragment.setBounds(taskBounds); + starting.info.flags |= FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; + + assertEquals(EMBEDDING_ALLOWED, canEmbedActivity(taskFragment, starting, task)); + + starting.info.flags &= ~FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; + // Set task fragment's uid as the same as starting activity's uid. + taskFragment.setTaskFragmentOrganizer(mock(TaskFragmentOrganizerToken.class), + UNIMPORTANT_UID, "test"); + + assertEquals(EMBEDDING_ALLOWED, canEmbedActivity(taskFragment, starting, task)); + + // Make task fragment bounds smaller than starting activity's minimum dimensions + taskFragment.setBounds(0, 0, minDimensions.getWidth() - 1, minDimensions.getHeight() - 1); + + assertEquals(EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, + canEmbedActivity(taskFragment, starting, task)); + } + private static void startActivityInner(ActivityStarter starter, ActivityRecord target, ActivityRecord source, ActivityOptions options, Task inTask, TaskFragment inTaskFragment) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 71f19148d616..b5764f54ff92 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -87,7 +87,7 @@ public class AppChangeTransitionTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 8656a4fecef1..f2d6273f2b26 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -806,7 +806,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { mFinishedCallback = null; } 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 436cf36587d8..74154609b22e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -522,7 +522,7 @@ public class AppTransitionTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { mCancelled = true; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index d737963f80e7..40e266c71328 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1699,6 +1699,13 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(displayContent.mPinnedTaskController.isFreezingTaskConfig(pinnedTask)); assertEquals(pinnedActivity.getConfiguration().orientation, displayContent.getConfiguration().orientation); + + // No need to apply rotation if the display ignores orientation request. + doCallRealMethod().when(displayContent).rotationForActivityInDifferentOrientation(any()); + pinnedActivity.mOrientation = SCREEN_ORIENTATION_LANDSCAPE; + displayContent.setIgnoreOrientationRequest(true); + assertEquals(WindowConfiguration.ROTATION_UNDEFINED, + displayContent.rotationForActivityInDifferentOrientation(pinnedActivity)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 1708ed7d4686..83f375f85fa3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1332,7 +1332,7 @@ public class RecentTasksTest extends WindowTestsBase { }); assertSecurityException(expectCallable, () -> mAtm.startActivityFromRecents(0, new Bundle())); - assertSecurityException(expectCallable, () -> mAtm.getTaskSnapshot(0, true)); + assertSecurityException(expectCallable, () -> mAtm.getTaskSnapshot(0, true, false)); assertSecurityException(expectCallable, () -> mAtm.registerTaskStackListener(null)); assertSecurityException(expectCallable, () -> mAtm.unregisterTaskStackListener(null)); diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 204c7e6fb8d4..027f5218f820 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -43,6 +43,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -210,7 +211,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); adapter.onAnimationCancelled(mMockLeash); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -226,7 +227,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mClock.fastForward(10500); mHandler.timeAdvance(); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } @@ -247,12 +248,12 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mClock.fastForward(10500); mHandler.timeAdvance(); - verify(mMockRunner, never()).onAnimationCancelled(); + verify(mMockRunner, never()).onAnimationCancelled(anyBoolean()); mClock.fastForward(52500); mHandler.timeAdvance(); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } finally { @@ -264,7 +265,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { public void testZeroAnimations() throws Exception { mController.goodToGo(TRANSIT_OLD_NONE); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -274,7 +275,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -316,7 +317,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { win.mActivityRecord.removeImmediately(); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } @@ -574,7 +575,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { // Cancel the wallpaper window animator and ensure the runner is not canceled wallpaperWindowToken.cancelAnimation(); - verify(mMockRunner, never()).onAnimationCancelled(); + verify(mMockRunner, never()).onAnimationCancelled(anyBoolean()); } finally { mDisplayContent.mOpeningApps.clear(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 1c3b869e02d0..e47bcc98b908 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.testing.Assert.assertThrows; @@ -530,7 +531,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mWindowOrganizerController.mLaunchTaskFragments .put(mFragmentToken, mTaskFragment); mTransaction.reparentActivityToTaskFragment(mFragmentToken, activity.token); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); + doReturn(EMBEDDING_ALLOWED).when(mTaskFragment).isAllowedToEmbedActivity(activity); clearInvocations(mAtm.mRootWindowContainer); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); @@ -920,7 +921,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .setOrganizer(mOrganizer) .setBounds(mTaskFragBounds) .build(); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); // Reparent activity to mTaskFragment, which is smaller than activity's @@ -956,7 +956,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .setOrganizer(mOrganizer) .setBounds(mTaskFragBounds) .build(); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); mWindowOrganizerController.mLaunchTaskFragments.put(oldFragToken, oldTaskFrag); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index ab72a0f72671..e1fbf96b2e71 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -683,6 +683,7 @@ public class TransitionTests extends WindowTestsBase { assertTrue(ime.mToken.inTransition()); assertTrue(task.inTransition()); assertTrue(asyncRotationController.isTargetToken(decorToken)); + assertTrue(asyncRotationController.shouldFreezeInsetsPosition(navBar)); screenDecor.setOrientationChanging(false); // Status bar finishes drawing before the start transaction. Its fade-in animation will be diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index 996382782b84..fba4ff1f1c25 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -246,6 +246,22 @@ public class WallpaperControllerTests extends WindowTestsBase { assertEquals(otherWindowInitialZoom, wallpaperWindow.mWallpaperZoomOut, .01f); } + @Test + public void testUpdateWallpaperTarget() { + final DisplayContent dc = mDisplayContent; + final WindowState homeWin = createWallpaperTargetWindow(dc); + final WindowState appWin = createWindow(null, TYPE_BASE_APPLICATION, "app"); + final RecentsAnimationController recentsController = mock(RecentsAnimationController.class); + doReturn(true).when(recentsController).isWallpaperVisible(eq(appWin)); + mWm.setRecentsAnimationController(recentsController); + + dc.mWallpaperController.adjustWallpaperWindows(); + assertEquals(appWin, dc.mWallpaperController.getWallpaperTarget()); + // The wallpaper target is gone, so it should adjust to the next target. + appWin.removeImmediately(); + assertEquals(homeWin, dc.mWallpaperController.getWallpaperTarget()); + } + /** * Tests that the windowing mode of the wallpaper window must always be fullscreen. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 5743922d0428..1715a295ded3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -979,7 +979,7 @@ public class WindowContainerTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }, 0, 0, false); adapter.setCallingPidUid(123, 456); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index e09a94f3bcf9..1a64f5e3a356 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -61,6 +61,7 @@ import android.view.InsetsState; import android.view.InsetsVisibilities; import android.view.View; import android.view.WindowManager; +import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; @@ -317,4 +318,76 @@ public class WindowManagerServiceTests extends WindowTestsBase { verify(mWm.mInputManager).setInTouchMode( !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false); } + + @Test + public void testGetTaskWindowContainerTokenForLaunchCookie_nullCookie() { + WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(null); + assertThat(wct).isNull(); + } + + @Test + public void testGetTaskWindowContainerTokenForLaunchCookie_invalidCookie() { + Binder cookie = new Binder("test cookie"); + WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie); + assertThat(wct).isNull(); + + final ActivityRecord testActivity = new ActivityBuilder(mAtm) + .setCreateTask(true) + .build(); + + wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie); + assertThat(wct).isNull(); + } + + @Test + public void testGetTaskWindowContainerTokenForLaunchCookie_validCookie() { + final Binder cookie = new Binder("ginger cookie"); + final WindowContainerToken launchRootTask = mock(WindowContainerToken.class); + setupActivityWithLaunchCookie(cookie, launchRootTask); + + WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie); + assertThat(wct).isEqualTo(launchRootTask); + } + + @Test + public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies() { + final Binder cookie1 = new Binder("ginger cookie"); + final WindowContainerToken launchRootTask1 = mock(WindowContainerToken.class); + setupActivityWithLaunchCookie(cookie1, launchRootTask1); + + setupActivityWithLaunchCookie(new Binder("choc chip cookie"), + mock(WindowContainerToken.class)); + + setupActivityWithLaunchCookie(new Binder("peanut butter cookie"), + mock(WindowContainerToken.class)); + + WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie1); + assertThat(wct).isEqualTo(launchRootTask1); + } + + @Test + public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies_noneValid() { + setupActivityWithLaunchCookie(new Binder("ginger cookie"), + mock(WindowContainerToken.class)); + + setupActivityWithLaunchCookie(new Binder("choc chip cookie"), + mock(WindowContainerToken.class)); + + setupActivityWithLaunchCookie(new Binder("peanut butter cookie"), + mock(WindowContainerToken.class)); + + WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie( + new Binder("some other cookie")); + assertThat(wct).isNull(); + } + + private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) { + final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class); + when(remoteToken.toWindowContainerToken()).thenReturn(wct); + final ActivityRecord testActivity = new ActivityBuilder(mAtm) + .setCreateTask(true) + .build(); + testActivity.mLaunchCookie = launchCookie; + testActivity.getTask().mRemoteToken = remoteToken; + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 08bad70a1411..9c2aac066084 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -223,7 +223,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer); // Ensure events dispatch to organizer. mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); - assertTaskVanished(organizer, false /* expectVanished */, rootTask); + verify(organizer, times(0)).onTaskVanished(any()); assertFalse(rootTask.isOrganized()); } @@ -297,7 +297,7 @@ public class WindowOrganizerTests extends WindowTestsBase { // Ensure events dispatch to organizer. mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); - assertTaskVanished(organizer, true /* expectVanished */, rootTask); + verify(organizer, times(0)).onTaskVanished(any()); assertFalse(rootTask.isOrganized()); } @@ -341,7 +341,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); verify(organizer, times(3)) .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); - assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -395,6 +395,7 @@ public class WindowOrganizerTests extends WindowTestsBase { assertFalse(task2.isAttached()); // Normal task should keep. assertTrue(task.isAttached()); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -439,7 +440,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); verify(organizer, times(3)) .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); - assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -1264,7 +1265,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription")); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_APPEARED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1284,7 +1285,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.removeImmediately(); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(0, pendingEvents.size()); } @@ -1302,7 +1303,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription")); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1311,7 +1312,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription2")); waitUntilHandlersIdle(); - pendingEvents = getTaskPendingEvent(rootTask); + pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType); assertEquals("TestDescription2", @@ -1334,7 +1335,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.removeImmediately(); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1355,7 +1356,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); } @@ -1375,14 +1376,16 @@ public class WindowOrganizerTests extends WindowTestsBase { new IRequestFinishCallback.Default()); waitUntilHandlersIdle(); - ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(rootTask); + ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); } - private ArrayList<PendingTaskEvent> getTaskPendingEvent(Task task) { + private ArrayList<PendingTaskEvent> getTaskPendingEvent(ITaskOrganizer organizer, Task task) { ArrayList<PendingTaskEvent> total = - mWm.mAtmService.mTaskOrganizerController.getPendingEventList(); + mWm.mAtmService.mTaskOrganizerController + .getTaskOrganizerPendingEvents(organizer.asBinder()) + .getPendingEventList(); ArrayList<PendingTaskEvent> result = new ArrayList(); for (int i = 0; i < total.size(); i++) { |